bzoj 3551: [ONTAK2010]Peaks加强版
3551: [ONTAK2010]Peaks加强版
Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 3889 Solved: 1143
[Submit][Status][Discuss]
Description
【题目描述】同3545
Input
第一行三个数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
同3545
Sample Input
Sample Output
HINT
【数据范围】同3545
这题是kruskal重构树,这题一定要在线,而3545可以离线,离线的话我们可以排序以后用线段树合并维护连通性。
构树以后,由于答案都在子树里面,而子树在dfs序里面是一个连续的区间,所以我们维护一个主席树。
1 #include<bits/stdc++.h> 2 using namespace std; 3 int const N=200000+10; 4 int const M=500000+10; 5 #define mid (l+r)/2 6 struct edge{ 7 int to,nt; 8 }e[N]; 9 struct E{ 10 int x,y,z; 11 bool operator < (const E &rhs) const{ 12 return z<rhs.z; 13 } 14 }t[M]; 15 int a[N],b[N],n,m,q,c[N],f[N],val[N],h[N],cnt,sum[N*20],rt[N],tin[N],tout[N],T,id[N],lch[N*20],rch[N*20]; 16 int d[N][20],anc[N][20]; 17 void read(int &x){ 18 x=0; char c=getchar(); 19 while (!isdigit(c)) c=getchar(); 20 while (isdigit(c)) x=x*10+(c^48),c=getchar(); 21 } 22 int find(int x){ 23 return x==f[x]? x: f[x]=find(f[x]); 24 } 25 void add(int a,int b){ 26 e[++cnt].to=b; 27 e[cnt].nt=h[a]; 28 h[a]=cnt; 29 } 30 void kruscal(){ 31 int id=n; 32 for(int i=1;i<2*n;i++) f[i]=i; 33 for(int i=1;i<=m;i++){ 34 int fx=find(t[i].x); 35 int fy=find(t[i].y); 36 if(fx!=fy){ 37 id++; 38 f[fx]=f[fy]=id; 39 val[id]=t[i].z; 40 add(id,fx); 41 add(id,fy); 42 d[fx][0]=d[fy][0]=t[i].z; 43 anc[fx][0]=anc[fy][0]=id; 44 if(id==2*n-1) break; 45 } 46 } 47 } 48 void dfs(int x){ 49 tin[x]=++T; 50 id[T]=x; 51 for(int i=h[x];i;i=e[i].nt){ 52 int v=e[i].to; 53 dfs(v); 54 } 55 tout[x]=T; 56 } 57 void insert(int now,int &x,int l,int r,int p){ 58 x=++cnt; 59 lch[x]=lch[now];rch[x]=rch[now];sum[x]=sum[now]; 60 if(l==r) { 61 sum[x]++; 62 return; 63 } 64 if(p<=mid) insert(lch[now],lch[x],l,mid,p); 65 else insert(rch[now],rch[x],mid+1,r,p); 66 sum[x]=sum[lch[x]]+sum[rch[x]]; 67 } 68 int query(int x,int y,int l,int r,int k){ 69 if(l==r) return b[r]; 70 int num=sum[lch[y]]-sum[lch[x]]; 71 if(num>=k) return query(lch[x],lch[y],l,mid,k); 72 else return query(rch[x],rch[y],mid+1,r,k-num); 73 } 74 int main(){ 75 //scanf("%d%d%d",&n,&m,&q); 76 read(n);read(m); read(q); 77 for(int i=1;i<=n;i++) 78 read(a[i]),b[i]=a[i]; 79 sort(b+1,b+n+1); 80 int rk=unique(b+1,b+n+1)-b-1; 81 for(int i=1;i<=n;i++) 82 c[i]=lower_bound(b+1,b+rk+1,a[i])-b; 83 int last=0; 84 for(int i=1;i<=m;i++) 85 // scanf("%d%d%d",&t[i].x,&t[i].y,&t[i].z); 86 read(t[i].x),read(t[i].y),read(t[i].z); 87 sort(t+1,t+m+1); 88 kruscal(); 89 cnt=0; 90 for(int i=2*n-1;i>=1;i--) 91 if(!tin[i]) { 92 anc[i][0]=i; 93 dfs(i); 94 } 95 /* 96 for(int i=2*n-1;i>=1;i--){ 97 cout<<i<<"*** "<<val[i]<<" ** "; 98 for(int j=h[i];j;j=e[j].nt){ 99 cout<<e[j].to<<" "; 100 } 101 cout<<endl; 102 } */ 103 for(int j=1;j<20;j++) 104 for(int i=1;i<2*n;i++){ 105 d[i][j]=max(d[i][j-1],d[anc[i][j-1]][j-1]); 106 anc[i][j]=anc[anc[i][j-1]][j-1]; 107 } 108 for(int i=1;i<2*n;i++){ 109 if(id[i]<=n) insert(rt[i-1],rt[i],1,rk,c[id[i]]); 110 else rt[i]=rt[i-1]; 111 } 112 while (q--){ 113 int v,x,k; 114 // scanf("%d%d%d",&v,&x,&k); 115 read(v); read(x);read(k); 116 if(last!=-1){ 117 v^=last; 118 x^=last; 119 k^=last; 120 } 121 int t=v; 122 for(int i=19;i>=0;i--) 123 if(d[t][i]<=x) t=anc[t][i]; 124 int l=tin[t]; 125 int r=tout[t]; 126 int num=sum[rt[r]]-sum[rt[l-1]]; 127 if(num<k) printf("%d\n",last=-1); 128 else { 129 k=num-k+1; 130 //cout<<"nima"<<k<<endl; 131 printf("%d\n",last=query(rt[l-1],rt[r],1,rk,k)); 132 } 133 //last=0; 134 } 135 return 0; 136 137 }