Bzoj3551:[ONTAK2010]Peaks加強版:Kruskal+主席樹__BZOJ

來源:互聯網
上載者:User

題目連結:[ONTAK2010]Peaks加強版

做一遍Kruscal,對於要合并聯通塊的兩個點x,y建立節點z令fa[x]=fa[y]=z,並且節點z的權值為這條邊的邊權

那麼我們對於一個詢問<v,x,k>只需要倍增出最後一個權值>x的節點,這顆子樹就是我們要找到的聯通塊

主席樹維護即可

#include<cstdio>#include<cstdlib>#include<iostream>#include<algorithm>using namespace std;const int maxn=300010;const int maxN=5000000;const int inf=0x7fffffff/2-1;int n,m,f[maxn],tmp[maxn],a[maxn];struct edge{int a,b,w;}e[maxn<<1];int lson[maxN],rson[maxN],T[maxn];int tot=0,cnt=0,N=0,totr=0,ind=0;int s[maxN],fa[maxn][20],st[maxn];int h[maxn],ed[maxn],dep[maxn],Q;struct edges{int to,next;}G[maxn<<2];int read(){    int x=0; char ch=getchar();    while(ch<'0'||ch>'9')ch=getchar();    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x;}int getpos(int x){int l=1,r=N,ret=-1;while (l<=r){int mid=(l+r)>>1;if (tmp[mid]>x) r=mid-1;else l=mid+1,ret=mid;}return ret;}bool cmp(const edge &a,const edge &b){return a.w<b.w;}int find(int x){return x==f[x]?x:f[x]=find(f[x]);}void add(int x,int y){G[++tot].to=y;G[tot].next=h[x];h[x]=tot;}void ins(int pre,int &rt,int l,int r,int pos){rt=++totr; s[rt]=s[pre]+1;if (l==r) return;int mid=(l+r)>>1;if (pos<=mid) rson[rt]=rson[pre],ins(lson[pre],lson[rt],l,mid,pos);else lson[rt]=lson[pre],ins(rson[pre],rson[rt],mid+1,r,pos);}void dfs(int x){dep[x]=dep[fa[x][0]]+1;st[x]=++ind;for (int i=1;i<=18;++i){if (dep[x]<(1<<i)) break;fa[x][i]=fa[fa[x][i-1]][i-1];}if (x<=n) ins(T[ind-1],T[ind],1,N,a[x]);else T[ind]=T[ind-1];for (int i=h[x];i;i=G[i].next){int v=G[i].to;fa[v][0]=x; dfs(v);}ed[x]=ind;}int query(int pre,int rt,int l,int r,int k){if (l==r) return tmp[l];int mid=(l+r)>>1,sum=s[rson[rt]]-s[rson[pre]];if (sum>=k) return query(rson[pre],rson[rt],mid+1,r,k);else return query(lson[pre],lson[rt],l,mid,k-sum);}int main(){n=read(); m=read(); Q=read(); cnt=n;for (int i=1;i<=n;++i) a[i]=read(),tmp[i]=a[i];sort(tmp+1,tmp+n+1); tmp[0]=-inf;for (int i=1;i<=n;++i) if (tmp[i]!=tmp[i-1]) tmp[++N]=tmp[i];for (int i=1;i<=n;++i) a[i]=getpos(a[i]);for (int i=1;i<=m;++i)e[i].a=read(),e[i].b=read(),e[i].w=read();sort(e+1,e+m+1,cmp); for (int i=1;i<n<<1;++i) f[i]=i;for (int i=1;i<=m;++i){int x=find(e[i].a),y=find(e[i].b);if (x!=y){f[x]=f[y]=++cnt;add(cnt,x); add(cnt,y);a[cnt]=e[i].w;if (cnt==(n<<1)-1) break;}}for (int i=1;i<=n;++i){int x=find(i);if (!st[x]) dfs(x);}int lastans=0; a[0]=inf; for (int i=1;i<=Q;++i){int x=read()^lastans,y=read()^lastans,z=read()^lastans;int rt=x;for (int j=18;j>=0;--j){if (dep[rt]<(1<<j)) continue;if (a[fa[rt][j]]<=y) rt=fa[rt][j];}if (s[T[ed[rt]]]-s[T[st[rt]-1]]<z) lastans=-1;else lastans=query(T[st[rt]-1],T[ed[rt]],1,N,z);printf("%d\n",lastans);lastans=lastans<0?0:lastans;}}


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.