[BZOJ3551][ONTAK2010]Peaks加强版

题目大意:
  一个图上有$n(n\le10^5)$个带权点,$m(m\le5\times10^5)$条带权边。有$q(q\le5\times10^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\n",ans?ans=tmp[ans]:-1); 
166     }
167     return 0;
168 }

 

posted @ 2018-04-03 19:32  skylee03  阅读(105)  评论(0编辑  收藏  举报