• [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 }
  • 相关阅读:
    MySQL------索引
    分组数据
    聚集函数
    Web的Java开发基础分享——学生信息管理系统(二)
    Web的Java开发基础分享——学生信息管理系统(一)
    shiny酷酷的第一篇CSDN博客
    vue2.0.js
    vue1.0.js的初步学习
    layui新手使用
    前端兼容性的一些问题
  • 原文地址:https://www.cnblogs.com/skylee03/p/8718124.html
Copyright © 2020-2023  润新知