bzoj3545: [ONTAK2010]Peaks(主席樹+最小生成樹)
題目傳送門
。
解法:
好題啊。
只會不強制線上的。
強制線上的表示不會。
離線。
首先x可以到達的點其實都可以互相到達。
那麼我們可以看作是一個聯通塊。
要求邊權儘量小其實就是最小生成樹啊。
離線首先按每次詢問的x排序。
然後依次建小於等於x的最小生成樹。
那麼當前v所在的聯通塊的第k大實際上就是答案。
並查集壓縮路徑的時候合併一下主席樹即可。
吐槽:
時限太少了。40s好不好。
本機太慢每個點跑了5秒。
提交TLE。
這時候當然是找卡常大神來優化啦。
太神了%%%。
玄學快速讀.
還有一堆我以前程式碼裡找不到的東西。。
把我五秒的程式硬是弄到三秒。
然後7000ms+過了
程式碼實現:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
inline char nc() {
static char buf[1000000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
}
inline int read(void) {
char ch=nc();
int sum=0;
while(!(ch>='0'&&ch<='9'))
ch=nc();
while(ch>='0'&&ch<='9')
sum=(sum<<3)+(sum<<1)+(ch^48),ch=nc();
return sum;
}
struct node {int lc,rc,c;}t[2000001];int cnt,rt[200001];
inline void build(int &u,int l,int r,int p) {
if(u==0)u=++cnt;t[u].c++;
if(l==r)return ;int mid=(l+r)/2;
if(p<=mid)build(t[u].lc,l,mid,p);
else build(t[u].rc,mid+1,r,p);
}
int fa[100001];inline int findfa(int x) {if(fa[x]!=x)fa[x]=findfa(fa[x]);return fa[x];}
void Merge(int &u1,int u2) {
if(u1==0) {u1=u2;return ;}if(u2==0)return ;
t[u1].c+=t[u2].c;
Merge(t[u1].lc,t[u2].lc);
Merge(t[u1].rc,t[u2].rc);
}
int S[100001];
inline int find(int u,int l,int r,int k) {
if(t[u].c<k)return -1;
if(l==r)return S[l];
int mid=(l+r)/2;
if(k<=t[t[u].rc].c)return find(t[u].rc,mid+1,r,k);
else return find(t[u].lc,l,mid,k-t[t[u].rc].c);
}
struct trnode {int x,y,c,id,ans;}a[500001],Q[500001];int len;
bool cmp(trnode n1,trnode n2) {return n1.c<n2.c;}
bool cmp2(trnode n1,trnode n2) {return n1.y<n2.y;}
struct edge {int x,id;}s[500001];
bool cmp1(edge n1,edge n2) {return n1.x<n2.x;}
bool cmp3(trnode n1,trnode n2) {return n1.id<n2.id;}
int main() {
//freopen("3545.in","r",stdin);freopen("3545.out","w",stdout);
int n,m;n=read(),len=read(),m=read();cnt=0;
for(int i=1;i<=n;i++) {s[i].x=read();s[i].id=i;}
sort(s+1,s+1+n,cmp1);int tot=0;
for(int i=1;i<=n;i++) {
if(s[i].x!=s[i-1].x)tot++;S[tot]=s[i].x;
build(rt[s[i].id],1,n,tot);
}
for(register int i=1;i<=len;++i) {a[i].x=read();a[i].y=read();a[i].c=read();}
for(register int i=1;i<=m;++i) {
Q[i].x=read();Q[i].y=read();Q[i].c=read();Q[i].id=i;
}
for(int i=1;i<=n;++i)fa[i]=i;
sort(a+1,a+len+1,cmp);sort(Q+1,Q+1+m,cmp2);int tt=1;
for(register int i=1;i<=m;++i) {
for(register int j=tt;j<=len;++j) {
if(a[j].c>Q[i].y) {tt=j;break;}
int xx=findfa(a[j].x),yy=findfa(a[j].y);
if(xx!=yy) {fa[xx]=yy;Merge(rt[yy],rt[xx]);}
if(j==len)tt=len+1;
}Q[i].ans=find(rt[findfa(Q[i].x)],1,n,Q[i].c);
}sort(Q+1,Q+1+m,cmp3);
for(int i=1;i<=m;i++)printf("%d\n",Q[i].ans);
return 0;
}
相關文章
- 洛谷P4197 Peaks(Kruskal重構樹 主席樹)
- 最小生成樹
- 最小度限制生成樹
- 【模板】最小生成樹
- 主席樹
- 【圖論】最小生成樹圖論
- 圖的最小生成樹
- 【模板】最小生成樹-kruskal
- 最小生成樹專項
- 圖論 最小生成樹圖論
- 主席樹模板
- prim 樸素 最小生成樹
- Prim 最小生成樹 圖解圖解
- 專題六 最小生成樹【Kuangbin】
- 最小生成樹的演算法演算法
- 最小生成樹__Kurskal演算法演算法
- 最小生成樹__Prim演算法演算法
- 最小生成樹學習筆記筆記
- Networking POJ - 1287(kuangbin最小生成樹)
- 靜態主席樹模板
- 動態主席樹模板
- cf888G. Xor-MST(Boruvka最小生成樹 Trie樹)
- C135 線段樹分治 P5631 最小mex生成樹
- UVA1379——Slim Span (最小生成樹)
- 【演算法學習】最小生成樹演算法
- 一些“最小生成樹”板題
- NOIP 複習題之最小生成樹
- 演算法-圖論-最小生成樹演算法圖論
- 最小生成樹之 Prim 演算法演算法
- CH 6201 走廊潑水節 最小生成樹
- 最小生成樹(MinSpanTree)的Kruskal演算法演算法
- (樹_)求最小深度
- 圖論中的最小生成樹演算法圖論演算法
- Boruvka求最小生成樹(菠蘿演算法)演算法
- bzoj3714: [PA2014]Kuglarz(最小生成樹)
- 淺談三種求最小生成樹的方法
- 北極通訊網路——最小生成樹kruskal
- 最小生成樹prim普里姆演算法演算法