【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\n",ans); 132 } 133 return 0; 134 }