题目大意:
一个图上有$n(nle10^5)$个带权点,$m(mle5 imes10^5)$条带权边。有$q(qle5 imes10^5)$组询问,每次询问从点$v$出发,只经过权值小于等于$x$的边能到达的点中,权值第$k$大的点权。强制在线。
思路:
不强制在线时显然可以线段树合并。在线时需要建立Kruskal重构树,并对其DFS序建立主席树维护权值出现次数,每次询问结点权值小于等于$x$的虚点祖先所在的子树,求子树第$k$大值。
1 #include<cstdio> 2 #include<cctype> 3 #include<cstring> 4 #include<climits> 5 #include<algorithm> 6 #include<sys/mman.h> 7 #include<sys/stat.h> 8 class MMapInput { 9 private: 10 char *buf,*p; 11 int size; 12 public: 13 MMapInput() { 14 register int fd=fileno(stdin); 15 struct stat sb; 16 fstat(fd,&sb); 17 size=sb.st_size; 18 buf=reinterpret_cast<char*>(mmap(0,size,PROT_READ,MAP_PRIVATE,fileno(stdin),0)); 19 p=buf; 20 } 21 char getchar() { 22 return (p==buf+size||*p==EOF)?EOF:*p++; 23 } 24 }; 25 MMapInput mmi; 26 inline int getint() { 27 register char ch; 28 while(!isdigit(ch=mmi.getchar())); 29 register int x=ch^'0'; 30 while(isdigit(ch=mmi.getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 31 return x; 32 } 33 const int N=1e5+1,N2=N<<1,logN=18,logN2=18,M=5e5,M2=N2; 34 bool vis[N2]; 35 int n,m,q,tmp[N],h[N2],val[N2]={INT_MAX},dep[N2],anc[N2][logN2],in[N2],out[N2],cnt,tot,sz; 36 struct Edge { 37 int u,v,w; 38 bool operator < (const Edge &another) const { 39 return w<another.w; 40 } 41 }; 42 Edge e[M]; 43 struct DisjointSet { 44 int anc[N2]; 45 DisjointSet() { 46 for(register int i=0;i<N2;i++) anc[i]=i; 47 } 48 int find(const int &x) { 49 return x==anc[x]?x:anc[x]=find(anc[x]); 50 } 51 void merge(const int &x,const int &y) { 52 anc[find(x)]=find(y); 53 } 54 bool same(const int &x,const int &y) { 55 return find(x)==find(y); 56 } 57 }; 58 DisjointSet s; 59 struct Edge2 { 60 int to,next; 61 }; 62 Edge2 e2[M2]; 63 inline void add_edge(const int &u,const int &v) { 64 e2[sz]=(Edge2){v,h[u]};h[u]=sz++; 65 } 66 inline void kruskal() { 67 tot=n; 68 std::sort(&e[0],&e[m]); 69 for(register int i=0;i<m;i++) { 70 const int u=e[i].u,v=e[i].v,w=e[i].w; 71 if(!s.same(u,v)) { 72 val[++tot]=w; 73 add_edge(tot,s.find(u)); 74 add_edge(tot,s.find(v)); 75 s.merge(s.find(u),tot); 76 s.merge(s.find(v),tot); 77 } 78 } 79 } 80 inline int log2(const float &x) { 81 return ((unsigned&)x>>23&255)-127; 82 } 83 class SegmentTree { 84 private: 85 struct Node { 86 int val,left,right; 87 }; 88 Node node[N*logN]; 89 int sz,new_node(const int &p) { 90 node[++sz]=node[p]; 91 return sz; 92 } 93 void push_up(const int &p) { 94 node[p].val=node[node[p].left].val+node[node[p].right].val; 95 } 96 public: 97 int root[N2*2]; 98 void modify(int &p,const int &b,const int &e,const int &x) { 99 p=new_node(p); 100 if(b==e) { 101 node[p].val++; 102 return; 103 } 104 const int mid=(b+e)>>1; 105 if(x<=mid) modify(node[p].left,b,mid,x); 106 if(x>mid) modify(node[p].right,mid+1,e,x); 107 push_up(p); 108 } 109 int query(const int &p,const int &q,const int &b,const int &e,const int &k) { 110 if(node[q].val-node[p].val<k) return 0; 111 if(b==e) return b; 112 const int mid=(b+e)>>1; 113 if(node[node[q].right].val-node[node[p].right].val>=k) { 114 return query(node[p].right,node[q].right,mid+1,e,k); 115 } else { 116 return query(node[p].left,node[q].left,b,mid,k-(node[node[q].right].val-node[node[p].right].val)); 117 } 118 } 119 }; 120 SegmentTree t; 121 void dfs(const int &x,const int &par) { 122 vis[x]=true; 123 dep[x]=dep[anc[x][0]=par]+1; 124 for(register int i=1;i<=log2(dep[x]);i++) { 125 anc[x][i]=anc[anc[x][i-1]][i-1]; 126 } 127 in[x]=++cnt; 128 t.root[in[x]]=t.root[in[x]-1]; 129 for(register int i=h[x];~i;i=e2[i].next) { 130 const int &y=e2[i].to; 131 dfs(y,x); 132 } 133 out[x]=++cnt; 134 t.root[out[x]]=t.root[out[x]-1]; 135 if(x<=n) t.modify(t.root[out[x]],1,tmp[0],val[x]); 136 } 137 inline int find(int v,const int &x) { 138 for(register int i=log2(dep[v]);~i;i--) { 139 if(val[anc[v][i]]<=x) v=anc[v][i]; 140 } 141 return v; 142 } 143 int main() { 144 memset(h,-1,sizeof h); 145 n=getint(),m=getint(),q=getint(); 146 for(register int i=1;i<=n;i++) { 147 tmp[i]=val[i]=getint(); 148 } 149 std::sort(&tmp[1],&tmp[n]+1); 150 tmp[0]=std::unique(&tmp[1],&tmp[n]+1)-&tmp[1]; 151 for(register int i=1;i<=n;i++) { 152 val[i]=std::lower_bound(&tmp[1],&tmp[tmp[0]]+1,val[i])-&tmp[0]; 153 } 154 for(register int i=0;i<m;i++) { 155 const int u=getint(),v=getint(),w=getint(); 156 e[i]=(Edge){u,v,w}; 157 } 158 kruskal(); 159 for(register int i=1;i<=tot;i++) { 160 if(!vis[i]) dfs(s.find(i),0); 161 } 162 for(register int i=0,ans=0;i<q;i++) { 163 const int v=getint()^ans,x=getint()^ans,k=getint()^ans,p=find(v,x); 164 ans=t.query(t.root[in[p]],t.root[out[p]],1,tmp[0],k); 165 printf("%d ",ans?ans=tmp[ans]:-1); 166 } 167 return 0; 168 }