• 【20160815】noip模拟(未完)


      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 using namespace std;
      7 
      8 const int N=100010;
      9 int n,m,len;
     10 struct node{
     11     int x,y,d,next;
     12 }a[2*N];
     13 int first[N],f0[N],f1[N][20],g0[N],g1[N][20],tot[N];
     14 /*
     15 若m=0,
     16 f[x]:x的子树的节点到x的距离的总和
     17 g[x]:不是x的子树上的点到x的距离的总和
     18 f[x]=f[y]+d(x,y)*tot[y] y=all son[x]
     19 g[x]=f[fa]+g[fa] - (f[x]+tot[x]*d(x,fa)) + (n-tot[x])*d(x,fa)
     20 
     21 因为m<=15,异或只会影响最后四位数
     22 则将f[x]拆分为f0[x]:f[x]除去最后四位数的部分:xx0000
     23               f1[x][0~15]:f1[x][j]表示f[x]中有多少个最后四位为j的距离(不能像原来一样直接加进去,因为最后要异或)
     24 g[x]同理。
     25 */
     26 
     27 void ins(int x,int y,int d)
     28 {
     29     len++;
     30     a[len].x=x;a[len].y=y;a[len].d=d;
     31     a[len].next=first[x];first[x]=len;
     32 }
     33 
     34 void dfs1(int x,int fa)
     35 {
     36     f1[x][0]=1;//debug
     37     tot[x]=1;
     38     for(int i=first[x];i;i=a[i].next)
     39     {
     40         int y=a[i].y;
     41         if(y!=fa)
     42         {
     43             dfs1(y,x);
     44             tot[x]+=tot[y];
     45             // f[x]+=f[y]+a[i].d*tot[y];
     46             int now=a[i].d;
     47             f0[x]+=f0[y]+tot[y]*(now-(now%16));
     48             for(int j=0;j<=15;j++)
     49             {
     50                 int t=j+now%16;
     51                 f1[x][t%16]+=f1[y][j];
     52                 f0[x]+=(t-(t%16))*f1[y][j];
     53             }
     54         }
     55     }
     56 }
     57 
     58 void dfs2(int x,int fa)
     59 {
     60     for(int i=first[x];i;i=a[i].next)
     61     {
     62         int y=a[i].y;
     63         if(y!=fa)
     64         {
     65             // g[y]=f[x]+g[x]-f[y]+(n-2*tot[y])*a[i].d;
     66             // g[y]=f[x]+g[x] - (f[y]+tot[y]*a[i].d) + (n-tot[y])*a[i].d
     67             
     68             /*
     69             减法不会出现不够减:
     70             因为减的东西之前一定加过(所以要考虑它的实际意义)
     71             */
     72             
     73             //z c  f[y]+tot[y]*a[i].d
     74             int z=0,c[20];
     75             memset(c,0,sizeof(c));
     76             int now=a[i].d;
     77             z+=f0[y]+tot[y]*(now-(now%16));
     78             for(int j=0;j<=15;j++)
     79             {
     80                 int t=j+now%16;
     81                 c[t%16]+=f1[y][j];//以y为根的子树中每个点都要加d(x,y),j变为t%16
     82                 z+=(t-(t%16))*f1[y][j];
     83             }
     84             
     85             //g[y]=f[x]+g[x]-(f[y]+tot[y]*a[i].d)
     86             g0[y]+=f0[x]+g0[x]-z;
     87             for(int j=0;j<=15;j++) g1[y][j]+=f1[x][j]+g1[x][j]-c[j];
     88             
     89             //g[y]+=(n-tot[y])*a[i].d
     90             for(int j=0;j<=15;j++) c[j]=g1[y][j];
     91             for(int j=0;j<=15;j++) 
     92             {
     93                 int t=j+now;
     94                 g1[y][t%16]=c[j];
     95                 g0[y]+=(t-(t%16))*c[j];
     96             }
     97             dfs2(y,x);
     98         }
     99     }
    100 }
    101 
    102 int main()
    103 {
    104     // freopen("a.in","r",stdin);
    105     freopen("warehouse.in","r",stdin);
    106     freopen("warehouse.out","w",stdout);
    107     len=0;
    108     memset(first,0,sizeof(first));
    109     scanf("%d%d",&n,&m);
    110     for(int i=1;i<n;i++)
    111     {
    112         int x,y,d;
    113         scanf("%d%d%d",&x,&y,&d);
    114         ins(x,y,d),ins(y,x,d);
    115     }
    116     memset(f0,0,sizeof(f0));
    117     memset(f1,0,sizeof(f1));
    118     memset(g0,0,sizeof(g0));
    119     memset(g1,0,sizeof(g1));
    120     dfs1(1,0);dfs2(1,0);
    121     int ans=0;
    122     for(int i=1;i<=n;i++) 
    123     {
    124         ans=f0[i]+g0[i];
    125         for(int j=0;j<=15;j++)
    126         {
    127             int now=j^m;
    128             ans+=(f1[i][j]+g1[i][j])*now;
    129         }
    130         ans-=m;
    131         printf("%d
    ",ans);
    132     }
    133     return 0;
    134 }
  • 相关阅读:
    惊讶
    BLOG休假
    因考试得福
    Shape of My HeartSting !
    一个月的第一天了
    BLOG开张喽~~~
    该走了
    脏话
    EditText的属性
    游戏引擎
  • 原文地址:https://www.cnblogs.com/KonjakJuruo/p/5774339.html
Copyright © 2020-2023  润新知