• 联赛模拟测试9 C. 小奇的仓库(warehouse)


    题目描述



    分析

    (m=0) 是显然的换根 (dp)
    (m) 不为(0),沿用换根(dp)思路
    m的范围很小,加上异或是位运算
    先任选一个根,(dfs)求出 到每个点的距离之和 和 距离最后四位为(0 sim 15)的方案数
    (m=0)时差不多,随便搞一下就能写出换根的变化量

    代码

    #include<cstdio>
    #include<cstring>
    inline int read(){
    	int x=0,fh=1;
    	char ch=getchar();
    	while(ch<'0' || ch>'9'){
    		if(ch=='-') fh=-1;
    		ch=getchar();
    	}
    	while(ch>='0' && ch<='9'){
    		x=(x<<1)+(x<<3)+(ch^48);
    		ch=getchar();
    	}
    	return x*fh;
    }
    const int maxm=1e6+5,maxn=1e5+5;
    int head[maxm],tot=1;
    struct asd{
    	int to,next,val;
    }b[maxm];
    void ad(int aa,int bb,int cc){
    	b[tot].to=bb;
    	b[tot].next=head[aa];
    	b[tot].val=cc;
    	head[aa]=tot++;
    }
    int n,m,f[maxn],g[maxn],fcnt[maxn][16],gcnt[maxn][16],siz[maxn],zy[50];
    void debug(int now){
    	printf("begin-----debug
    ");
    	printf("--------------------
    ");
    	printf("g数组 节点编号 %d
    ",now);
    	for(int i=0;i<=15;i++){
    		if(gcnt[now][i])printf("长度:%d 数量:%d
    ",i,gcnt[now][i]);
    	}
    	printf(">16的长度 %d
    ",g[now]);
    	printf("f数组 节点编号 %d
    ",now);
    	for(int i=0;i<=15;i++){
    		if(fcnt[now][i])printf("长度:%d 数量:%d
    ",i,fcnt[now][i]);
    	}
    	printf(">16的长度 %d
    ",f[now]);
    	printf("end-----debug
    
    
    ");
    }
    #define findbug printf("当前节点:%d 父亲节点:%d 儿子节点:%d
    ",now,fa,u)
    void dfs(int now,int fa){
    	siz[now]=1;
    	for(int i=head[now];i!=-1;i=b[i].next){
    		int u=b[i].to;
    		if(u==fa) continue;
    		dfs(u,now);
    		int cs=b[i].val;
    		cs=(cs>>4);
    		cs=(cs<<4);
    		g[now]+=g[u]+cs*siz[u];
    		cs=(b[i].val&15);
    		for(int j=0;j<=30;j++){
    			zy[j]=0;
    		}
    		for(int j=0;j<=15;j++){
    			int nval=j+cs;
    			zy[nval]+=gcnt[u][j];
    		}
    		zy[cs]++;
    		for(int j=0;j<=30;j++){
    			if(j<=15){
    				gcnt[now][j]+=zy[j];
    			} else {
    				gcnt[now][j-16]+=zy[j];
    				g[now]+=zy[j]*16;
    			}
    		}
    		siz[now]+=siz[u];
    	}
    }
    void dfs2(int now,int fa){
    	if(now==1){
    		f[now]=g[now];
    		for(int i=0;i<=15;i++){
    			fcnt[now][i]=gcnt[now][i];
    		}
    	}
    	for(int i=head[now];i!=-1;i=b[i].next){
    		int u=b[i].to;
    		if(u==fa) continue;
    		int cs=b[i].val;
    		cs=(cs>>4);
    		cs=(cs<<4);
    		f[u]=f[now]-g[u]-siz[u]*cs;
    		f[u]+=(n-siz[u])*cs;
    		cs=(b[i].val&15);
    		for(int j=0;j<=30;j++){
    			zy[j]=0;
    		}
    		for(int j=0;j<=15;j++){
    			int nval=j+cs;
    			zy[nval]+=gcnt[u][j];
    		}
    		for(int j=0;j<=30;j++){
    			if(j<=15){
    				fcnt[u][j]=fcnt[now][j]-zy[j];
    			} else {
    				fcnt[u][j-16]-=zy[j];
    				f[u]-=zy[j]*16;
    			}
    		}
    		fcnt[u][cs]--;
    		for(int j=0;j<=30;j++){
    			zy[j]=0;
    		}
    		for(int j=0;j<=15;j++){
    			int nval=j+cs;
    			zy[nval]+=fcnt[u][j];
    		}
    		zy[cs]++;
    		for(int j=0;j<=30;j++){
    			if(j<=15){
    				fcnt[u][j]=gcnt[u][j]+zy[j];
    			} else {
    				fcnt[u][j-16]+=zy[j];
    				f[u]+=zy[j]*16;
    			}
    		}
    		f[u]+=g[u];
    		dfs2(u,now);
    	}
    }
    int main(){
    	freopen("warehouse.in","r",stdin);
    	freopen("warehouse.out","w",stdout);
    	memset(head,-1,sizeof(head));
    	n=read(),m=read();
    	int aa,bb,cc;
    	for(int i=1;i<n;i++){
    		aa=read(),bb=read(),cc=read();
    		ad(aa,bb,cc);
    		ad(bb,aa,cc);
    	}
    	dfs(1,0);
    	dfs2(1,0);
    	for(int i=1;i<=n;i++){
    		int nans=0;
    		for(int j=0;j<=15;j++){
    			nans=(nans+(j^m)*fcnt[i][j]);
    		}
    		printf("%d
    ",f[i]+nans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    算法图解-散列表
    算法图解-笔记
    ERROR:cannot read property 'getAttribute' of null 报错处理
    Error: Cannot find module 'node-sass' 报错处理
    一、Spring Cloud概述
    十、ActiveMQ多节点集群
    九、ActiveMQ的消息存储和持久化
    八、ActiveMQ的传输协议
    七、SpringBoot整合ActiveMQ
    六、Spring整合ActiveMQ
  • 原文地址:https://www.cnblogs.com/liuchanglc/p/13770392.html
Copyright © 2020-2023  润新知