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 }
