bzoj 3551: [ONTAK2010]Peaks加強版
阿新 • • 發佈:2017-08-05
-s out 表示 sca tex row 第k大 i++ gist
Description
【題目描述】同3545Input
第一行三個數N,M,Q。 第二行N個數,第i個數為h_i 接下來M行,每行3個數a b c,表示從a到b有一條困難值為c的雙向路徑。 接下來Q行,每行三個數v x k,表示一組詢問。v=v xor lastans,x=x xor lastans,k=k xor lastans。如果lastans=-1則不變。Output
同3545Sample Input
Sample Output
HINT
【數據範圍】同3545Source
Kruskal重構樹,就是在合並的時候新建一個節點,點權為邊權。。
有一些性質:
1.這是一棵二叉樹。(沒卵用)
2.原樹點都是葉子結點。
3.子結點比父結點點權小(大根堆)。
4.原樹與新樹兩點間路徑最大值與新樹相等,且等於新樹兩點lcalca點權。
所以只要從v點往上跳到深度最淺的<=x的點,然後查詢子樹第k大即可。。
然而死活RE,棄了棄了。。。
// MADE BY QT666 #include<cstdio> #include<algorithm> #include<cmath> #include<iostream> #include<cstring> #define RG register using namespace std; typedef long long ll; const int N=400050; int n,m,Q,sz,fa[N],rt[N],ls[N*20],rs[N*20],sum[N*20],hsh[N],Fa[N]; int id[N],dfn[N],ed[N],h[N],v[N],size[N],son[N],top[N]; struct data{ int a,b,c; }e[500050]; bool cmp(const data &a,const data &b){return a.c<b.c;} int head[N],to[N],nxt[N],cnt,tt,tot,res; inline void lnk(int x,int y){ to[++cnt]=y,nxt[cnt]=head[x],head[x]=cnt; } inline int find(int x){ if(x!=fa[x]) fa[x]=find(fa[x]); return fa[x]; } inline void dfs1(int x,int f){ size[x]=1; for(RG int i=head[x];i;i=nxt[i]){ int y=to[i]; if(y!=f){ Fa[y]=x;dfs1(y,x);size[x]+=size[y]; if(size[y]>size[son[x]]) son[x]=y; } } } inline void dfs2(int x,int ff){ dfn[x]=++tot;id[tot]=x;top[x]=ff; if(son[x]) dfs2(son[x],ff); for(RG int i=head[x];i;i=nxt[i]){ int y=to[i]; if(y!=Fa[x]&&y!=son[x]) dfs2(y,y); } ed[x]=tot; } inline void insert(RG int x,RG int &y,RG int l,RG int r,RG int u){ y=++sz;ls[y]=ls[x],rs[y]=rs[x];sum[y]=sum[x]+1; if(l==r) return; RG int mid=(l+r)>>1; if(u<=mid) insert(ls[x],ls[y],l,mid,u); else insert(rs[x],rs[y],mid+1,r,u); } inline int query(RG int x,RG int y,RG int l,RG int r,RG int k){ if(l==r) return l; RG int mid=(l+r)>>1; if(sum[ls[y]]-sum[ls[x]]>=k) return query(ls[x],ls[y],l,mid,k); else return query(rs[x],rs[y],mid+1,r,k-(sum[ls[y]]-sum[ls[x]])); } inline int jump(RG int x,RG int lim){ RG int j=x; while(x&&v[top[x]]<=lim){ j=top[x],x=Fa[top[x]]; } if(v[x]>lim||v[top[x]]<=lim) return j; RG int l=dfn[top[x]],r=dfn[x],ret=0; while(l<=r){ RG int mid=(l+r)>>1; if(v[id[mid]]<=lim) r=mid-1,ret=mid; else l=mid+1; } return id[ret]; } int main(){ freopen("Peaks.in","r",stdin); freopen("Peaks.out","w",stdout); scanf("%d%d%d",&n,&m,&Q); for(RG int i=1;i<=n;i++) scanf("%d",&h[i]),hsh[++res]=h[i]; for(RG int i=1;i<=m;i++) scanf("%d%d%d",&e[i].a,&e[i].b,&e[i].c); sort(e+1,e+1+m,cmp);for(int i=1;i<=n;i++) fa[i]=i;tt=n; for(RG int i=1;i<=m;i++){ RG int x=find(e[i].a),y=find(e[i].b); if(y!=x){ tt++;v[tt]=e[i].c;fa[x]=fa[y]=tt;fa[tt]=tt; lnk(tt,x);lnk(tt,y); } } for(RG int i=1;i<=tt;i++){ RG int g=find(i); if(!dfn[g]) dfs1(g,g),dfs2(g,g); } sort(hsh+1,hsh+res+1);res=unique(hsh+1,hsh+1+res)-hsh-1; for(RG int i=1;i<=tot;i++){ rt[i]=rt[i-1]; if(id[i]<=n) insert(rt[i],rt[i],1,res,lower_bound(hsh+1,hsh+1+res,h[id[i]])-hsh); } RG int lastans=0; while(Q--){ RG int u,x,k;scanf("%d%d%d",&u,&x,&k); u^=lastans,x^=lastans,k^=lastans; RG int Lca=jump(u,x); if(sum[rt[ed[Lca]]]-sum[rt[dfn[Lca]-1]]<k) puts("-1"),lastans=0; else lastans=query(rt[dfn[Lca]-1],rt[ed[Lca]],1,res,(sum[rt[ed[Lca]]]-sum[rt[dfn[Lca]-1]])-k+1),printf("%d\n",hsh[lastans]); } return 0; }
bzoj 3551: [ONTAK2010]Peaks加強版