zoukankan      html  css  js  c++  java
  • WISCO信息组NOIP模拟赛-部落冲突

    传送门


     首先肯定考虑树剖,这里没有要求区间加,所以可以用树状数组维护,不会卡常的

    这里是边权,可以转化为点权:让每条边连接的较深的节点的点权等于边权即可,然后计算的时候减去lca

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<algorithm>
      4 #include<cstring>
      5 #define MAXN 300005
      6 #define LOG 20
      7 using namespace std;
      8 int read(){
      9     int x=0;char ch=getchar();
     10     while(ch<'0'||ch>'9'){ch=getchar();}
     11     while(ch>='0'&&ch<='9'){x=x*10+(ch^48);ch=getchar();}
     12     return x;
     13 }
     14 int n,T;
     15 int a[MAXN],dat[MAXN];
     16 int dep[MAXN],size[MAXN],gs[MAXN],fa[20][MAXN];
     17 int top[MAXN],tree[MAXN],pre[MAXN],tot;
     18 int first[MAXN],nxt[MAXN<<1],to[MAXN<<1],cnt;
     19 int id[MAXN],tmp;
     20 
     21 void add(int x,int y){
     22     nxt[++cnt]=first[x];first[x]=cnt;to[cnt]=y;
     23     nxt[++cnt]=first[y];first[y]=cnt;to[cnt]=x;
     24 }
     25 int lca(int x,int y){
     26     if(dep[x]<dep[y]){
     27         swap(x,y);
     28     }
     29     for(int k=dep[x]-dep[y],p=0;k;k>>=1,p++){
     30         if(k&1){
     31             x=fa[p][x];
     32         }
     33     }
     34     if(x==y){
     35         return x;
     36     }
     37     for(int k=LOG-1;k>=0;k--){
     38         if(fa[k][x]!=fa[k][y]){
     39             x=fa[k][x],y=fa[k][y];
     40         }
     41     }
     42     return fa[0][x];
     43 }
     44 void change(int k,int x){
     45     while(k<=n){
     46         dat[k]+=x;
     47         k+=(k&-k);
     48     }
     49 }
     50 int query(int k){
     51     int ret=0;
     52     while(k>=1){
     53         ret+=dat[k];
     54         k-=(k&-k);
     55     }
     56     return ret;
     57 }
     58 void dfs1(int x){
     59     size[x]=1;
     60     for(int e=first[x];e;e=nxt[e]){
     61         int y=to[e];
     62         if(y==fa[0][x]){
     63             continue;
     64         }
     65         fa[0][y]=x;
     66         dep[y]=dep[x]+1;
     67         dfs1(y);
     68         size[x]+=size[y];
     69         if(size[y]>size[gs[x]]){
     70             gs[x]=y;
     71         }
     72     }
     73 }
     74 void dfs2(int x,int t){
     75     top[x]=t;
     76     tree[x]=(++tot);
     77     pre[tot]=x;
     78     if(!gs[x]){
     79         return;
     80     }
     81     dfs2(gs[x],t);
     82     for(int e=first[x];e;e=nxt[e]){
     83         int y=to[e];
     84         if(y==fa[0][x]||y==gs[x]){
     85             continue;
     86         }
     87         dfs2(y,y);
     88     }
     89 }
     90 int ask(int x,int y){
     91     int f1=top[x],f2=top[y];
     92     if(dep[f1]<dep[f2]){
     93         swap(x,y),swap(f1,f2);
     94     }
     95     int ret=-a[lca(x,y)];
     96     while(f1!=f2){
     97         ret+=query(tree[x])-query(tree[f1]-1);
     98         x=fa[0][f1]; f1=top[x];
     99         if(dep[f1]<dep[f2]){
    100             swap(x,y),swap(f1,f2);
    101         }    
    102     }
    103     if(dep[x]<dep[y]){
    104         swap(x,y);
    105     }
    106     ret+=query(tree[x])-query(tree[y]-1);
    107     return (ret<=0);
    108 }
    109 void init(){
    110     n=read();T=read();
    111     for(int i=1;i<n;i++){
    112         int x=read(),y=read();
    113         add(x,y);
    114     }
    115     dfs1(1);
    116     dfs2(1,1);
    117     for(int k=1;k<LOG;k++){
    118         for(int i=1;i<=n;i++){
    119             fa[k][i]=fa[k-1][fa[k-1][i]];
    120         }
    121     }
    122 }
    123 void solve(){
    124     char ch[5];
    125     while(T--){
    126         scanf("%s",ch);
    127         int x=read();
    128         if('Q'==ch[0]){
    129             int y=read();
    130             if(ask(x,y)){
    131                 printf("Yes
    ");
    132             }
    133             else{
    134                 printf("No
    ");
    135             }
    136         }
    137         else if('C'==ch[0]){
    138             int y=read();
    139             if(dep[x]<dep[y]){
    140                 swap(x,y);
    141             }
    142             change(tree[x],1);
    143             a[x]++;
    144             id[++tmp]=x;
    145         }
    146         else{
    147             x=id[x];
    148             change(tree[x],-1);
    149             a[x]--;
    150         }
    151     }
    152 }
    153 int main()
    154 {
    155     init();
    156     solve();
    157     return 0;
    158 }
    树剖AC

    也可以是树上差分,用树状数组+dfs序,本质上是差不多的

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<algorithm>
      4 #include<cstring>
      5 #define MAXN 300005
      6 #define LOG 20
      7 using namespace std;
      8 int read(){
      9     int x=0;char ch=getchar();
     10     while(ch<'0'||ch>'9'){ch=getchar();}
     11     while(ch>='0'&&ch<='9'){x=x*10+(ch^48);ch=getchar();}
     12     return x;
     13 }
     14 int n,T;
     15 int first[MAXN],nxt[MAXN<<1],to[MAXN<<1],cnt;
     16 int pin[MAXN],pout[MAXN],tot;
     17 int dat[MAXN<<1];
     18 int fa[LOG][MAXN],dep[MAXN];
     19 int id[MAXN],tmp;
     20 void change(int k,int x){
     21     while(k<=(n<<1)){
     22         dat[k]+=x;
     23         k+=(k&-k);
     24     }
     25 }
     26 int query(int k){
     27     int ret=0;
     28     while(k>=1){
     29         ret+=dat[k];
     30         k-=(k&-k);
     31     }
     32     return ret;
     33 }
     34 void add(int x,int y){
     35     nxt[++cnt]=first[x];first[x]=cnt;to[cnt]=y;
     36     nxt[++cnt]=first[y];first[y]=cnt;to[cnt]=x;
     37 }
     38 int lca(int x,int y){
     39     if(dep[x]<dep[y]){
     40         swap(x,y);
     41     }
     42     for(int k=dep[x]-dep[y],p=0;k;k>>=1,p++){
     43         if(k&1){
     44             x=fa[p][x];
     45         }
     46     }
     47     if(x==y){
     48         return x;
     49     }
     50     for(int k=LOG-1;k>=0;k--){
     51         if(fa[k][x]!=fa[k][y]){
     52             x=fa[k][x],y=fa[k][y];
     53         }
     54     }
     55     return fa[0][x];
     56 }
     57 void dfs(int x){
     58     pin[x]=(++tot);
     59     for(int e=first[x];e;e=nxt[e]){
     60         int y=to[e];
     61         if(y==fa[0][x]){
     62             continue;
     63         }
     64         dep[y]=dep[x]+1;
     65         fa[0][y]=x;
     66         dfs(y);
     67     }
     68     pout[x]=(++tot);
     69 }
     70 int ask(int x,int y){
     71     int t=query(pin[x])+query(pin[y])-2*query(pin[lca(x,y)]);
     72     return (t<=0);
     73 }
     74 void init(){
     75     n=read(); T=read();
     76     for(int i=1;i<n;i++){
     77         int x=read(),y=read();
     78         add(x,y);
     79     }    
     80     dfs(1);
     81     for(int k=1;k<LOG;k++){
     82         for(int i=1;i<=n;i++){
     83             fa[k][i]=fa[k-1][fa[k-1][i]];
     84         }
     85     }
     86 }
     87 void solve(){
     88     char ch[5]={0};
     89     while(T--){
     90         scanf("%s",ch);
     91         int x=read();
     92         if('Q'==ch[0]){
     93             int y=read();
     94             if(ask(x,y)){
     95                 printf("Yes
    ");
     96             }
     97             else{
     98                 printf("No
    ");
     99             }
    100         }
    101         else if('C'==ch[0]){
    102             int y=read();
    103             if(dep[x]<dep[y]){
    104                 swap(x,y);
    105             }
    106             change(pin[x],1);
    107             change(pout[x]+1,-1);
    108             id[++tmp]=x;
    109         }
    110         else{
    111             x=id[x];
    112             change(pin[x],-1);
    113             change(pout[x]+1,1);
    114         }
    115     }
    116 }
    117 int main()
    118 {
    119 //    freopen("data.in","r",stdin);
    120     init();
    121     solve();
    122     return 0;
    123 }
    树上差分AC
  • 相关阅读:
    检验Excel中数据是否与数据库中数据重复
    C# 上传文件
    asp.net Excel导入和导出
    完整ASP.Net Excel导入
    C#遍历指定文件夹中的所有文件
    C#获取文件夹下的所有文件的文件名
    UITextField 文本框 只能输入数字 且保留2位小数 实现
    Asp.Net生成无限级菜单
    给Repeater增加button事件,并绑定值
    简洁的Asp.net菜单控件
  • 原文地址:https://www.cnblogs.com/w-h-h/p/7780963.html
Copyright © 2011-2022 走看看