[Gym101194G][CHINA-Final2016]Pandaria

题目大意:
  给你一个$n(nle10^5)$个点,$m(mle2 imes10^5)$条边的无向图,每个点有一个颜色$c_i$,每条边有一个边权$w_i$。$q(qle2 imes10^5)$组询问$(x,w)$,每次询问从点$x$出发,只经过边权不超过$w$的边所能到达的连通块中,出现次数最多的颜色中,编号最小的颜色是多少?

思路:
  Kruskal重构树+线段树合并。时间复杂度$O(mlog m+qlog n)$。

  1 #include<cstdio>
  2 #include<cctype>
  3 #include<climits>
  4 #include<cstring>
  5 #include<algorithm>
  6 inline int getint() {
  7     register char ch;
  8     while(!isdigit(ch=getchar()));
  9     register int x=ch^'0';
 10     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
 11     return x;
 12 }
 13 const int N=2e5,logN=18,M=2e5;
 14 int n,m,tot,ch[N][2],val[N]={INT_MAX},ans[N];
 15 struct Edge {
 16     int u,v,w;
 17     bool operator < (const Edge &another) const {
 18         return w<another.w;
 19     }
 20 };
 21 Edge e[M];
 22 struct DisjointSet {
 23     int anc[N];
 24     void reset() {
 25         for(register int i=0;i<N;i++) anc[i]=i;
 26     }
 27     int find(const int &x) {
 28         return x==anc[x]?x:anc[x]=find(anc[x]);
 29     }
 30     void merge(const int &x,const int &y) {
 31         anc[find(x)]=find(y);
 32     }
 33     bool same(const int &x,const int &y) {
 34         return find(x)==find(y);
 35     }
 36 };
 37 DisjointSet s;
 38 inline void kruskal() {
 39     tot=n;
 40     s.reset();
 41     std::sort(&e[0],&e[m]);
 42     for(register int i=0;i<m;i++) {
 43         const int &u=e[i].u,&v=e[i].v,&w=e[i].w;
 44         if(!s.same(u,v)) {
 45             val[++tot]=w;
 46             ch[tot][0]=s.find(u);
 47             ch[tot][1]=s.find(v);
 48             s.merge(u,tot);
 49             s.merge(v,tot);
 50         }
 51     }
 52 }
 53 class SegmentTree {
 54     private:
 55         struct Node {
 56             int max,val,left,right;
 57         };
 58         Node node[N/2*logN];
 59         int new_node(const int &p) {
 60             node[++root[0]]=node[p];
 61             return root[0];
 62         }
 63         void push_up(const int &p) {
 64             if(node[node[p].left].max>=node[node[p].right].max) {
 65                 node[p].max=node[node[p].left].max;
 66                 node[p].val=node[node[p].left].val;
 67             } else {
 68                 node[p].max=node[node[p].right].max;
 69                 node[p].val=node[node[p].right].val;
 70             }
 71         }
 72     public:
 73         int root[N];
 74         void reset() {
 75             memset(root,0,sizeof root);
 76         }
 77         void modify(int &p,const int &b,const int &e,const int &x) {
 78             p=new_node(p);
 79             if(b==e) {
 80                 node[p]=(Node){1,x,0,0};
 81                 return;
 82             }
 83             const int mid=(b+e)>>1;
 84             if(x<=mid) modify(node[p].left,b,mid,x);
 85             if(x>mid) modify(node[p].right,mid+1,e,x);
 86             push_up(p);
 87         }
 88         int merge(const int &p,const int &q,const int &b,const int &e) {
 89             if(!p||!q) return p|q;
 90             if(b==e) {
 91                 node[p].max+=node[q].max;
 92                 return p;
 93             }
 94             const int mid=(b+e)>>1;
 95             node[p].left=merge(node[p].left,node[q].left,b,mid);
 96             node[p].right=merge(node[p].right,node[q].right,mid+1,e);
 97             push_up(p);
 98             return p;
 99         }
100         int query(const int &p) const {
101             return node[p].val;
102         }
103 };
104 SegmentTree t;
105 int dep[N],anc[N][logN];
106 inline int log2(const float &x) {
107     return ((unsigned&)x>>23&255)-127;
108 }
109 void dfs(const int &x,const int &par) {
110     dep[x]=dep[anc[x][0]=par]+1;
111     for(register int i=1;i<=log2(dep[x]);i++) {
112         anc[x][i]=anc[anc[x][i-1]][i-1];
113     }
114     if(x<=n) return;
115     dfs(ch[x][0],x);
116     dfs(ch[x][1],x);
117     t.root[x]=t.merge(t.root[ch[x][0]],t.root[ch[x][1]],1,n);
118     ans[x]=t.query(t.root[x]);
119 }
120 inline int find(int x,const int &w) {
121     for(register int i=log2(dep[x]);~i;i--) {
122         if(val[anc[x][i]]<=w) x=anc[x][i];
123     }
124     return x;
125 }
126 int main() {
127     const int T=getint();
128     for(register int i=1;i<=T;i++) {
129         t.reset();
130         n=getint(),m=getint();
131         for(register int i=1;i<=n;i++) {
132             t.modify(t.root[i],1,n,ans[i]=val[i]=getint());
133         }
134         for(register int i=0;i<m;i++) {
135             const int u=getint(),v=getint(),w=getint();
136             e[i]=(Edge){u,v,w};
137         }
138         kruskal();
139         dfs(tot,0);
140         printf("Case #%d:
",i);
141         for(register int q=getint(),last=0;q;q--) {
142             const int x=getint()^last,w=getint()^last;
143             printf("%d
",last=ans[find(x,w)]);
144         }
145     }
146     return 0;
147 }
原文地址:https://www.cnblogs.com/skylee03/p/8718124.html