• 树哈希与换根dp:CF763D


    采用的树哈希函数是:

    d p x = w x × ∑ y ∈ x d p y 2 + w x 2 \Large dp_x=w_x\times \sum_{y\in x}dp_y^2+w_x^2 dpx=wx×yxdpy2+wx2

    发现从 x x x y y y 时只有 x x x y y y 的哈希值会变化,分别维护即可

    #include
    using namespace std;
    #define int long long
    inline int read(){int x=0,f=1;char ch=getchar(); while(ch<'0'||
    ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){
    x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;}
    #define Z(x) (x)*(x)
    #define pb push_back
    //mt19937 rand(time(0));
    //mt19937_64 rand(time(0));
    //srand(time(0));
    #define N 100010
    //#define M
    #define mo (int)(1e9+123)
    int n, m, i, j, k, T;
    int pos, mx, cnt, h[N], w[N], dp[N], f[N], u, v; 
    map<int, int>mp; 
    vector<int>G[N]; 
    
    int Mod(int a) {
    	return (a%mo+mo)%mo; 
    }
    
    void add(int x, int k) {
    	mp[x]+=k; 
    	if(mp[x]==1 && k==1) ++cnt; 
    	if(mp[x]==0 && k==-1) --cnt; 
    //	printf("# %lld (%lld): %lld\n", x, mp[x], cnt); 
    }
    
    void dfs1(int x, int fa) {
    //	int s1, s2=0; 
    	w[x]=1; 
    	for(int y : G[x]) {
    		if(y==fa) continue; 
    		dfs1(y, x); 
    		w[x]+=w[y]; f[x]=Mod(f[x]+dp[y]*dp[y]); 
    	}
    	dp[x]=Mod(w[x]*f[x]%mo+w[x]*w[x]%mo); 
    	add(dp[x], 1); 
    //	printf("%lld : %lld\n", x, dp[x]); 
    }
    
    void dfs2(int x, int fa) {
    	int xw, xf, xdp, yw, yf, ydp; 
    	for(int y : G[x]) {
    		if(y==fa) continue; 
    //		printf("del [%lld] : %lld\n", x, dp[x]); 
    		add(dp[x], -1); xdp=dp[x]; xw=w[x]; xf=f[x]; 
    		w[x]=w[x]-w[y]; f[x]=Mod(f[x]-dp[y]*dp[y]); 
    		dp[x]=(w[x]*f[x]%mo+w[x]*w[x]%mo); 
    //		printf("ins [%lld] %lld : %lld\n", x, w[x], dp[x]); 
    		add(dp[x], 1); 
    		
    //		printf("del [%lld] : %lld\n", y, dp[y]); 
    
    		add(dp[y], -1); ydp=dp[y]; yw=w[y]; yf=f[y]; 
    		w[y]=n; f[y]=Mod(f[y]+dp[x]*dp[x])%mo; 
    		dp[y]=(w[y]*f[y]%mo+w[y]*w[y]%mo); 
    		
    //		printf("ins [%lld] : %lld\n", y, dp[y]); 
    		add(dp[y], 1); 
    		
    //		printf("%lld : %lld\n", y, cnt); 
    //		for(auto t=mp.begin(); t!=mp.end(); ++t) printf("%lld ", t); 
    		if(cnt>mx) mx=cnt, pos=y; 
    		
    		dfs2(y, x); 
    		
    		add(dp[x], -1); add(dp[y], -1); 
    		dp[x]=xdp; w[x]=xw; f[x]=xf; add(dp[x], 1); 
    		dp[y]=ydp; w[y]=yw; f[y]=yf; add(dp[y], 1); 
    	}
    }
    
    signed main()
    {
    //	freopen("in.txt", "r", stdin);
    //	freopen("out.txt", "w", stdout);
    //	T=read();
    //	while(T--) {
    //
    //	}
    	n=read(); 
    	for(i=1, k=1; i<n; ++i) {
    		u=read(); v=read(); 
    		G[u].pb(v); G[v].pb(u); 
    	} 
    	dfs1(1, 0); 
    	mx=cnt; pos=1; 
    	dfs2(1, 0); 
    	printf("%lld", pos); 
    	return 0;
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
  • 相关阅读:
    计组笔记(1)——校验码、原补码乘除计算、浮点数计算
    【Rust日报】2022-09-19 测量 CPU 不同核心之间的延迟
    Mybatis-Plus的使用
    Spring中的拦截器HandlerInterceptor
    里程碑,用自己的编程语言实现了一个网站
    Java8实战-总结48
    Linux中的主要系统调用
    R语言根据名称排除数据框中的列:使用列名从data.frame中排除指定的数据列
    如何解决分布式场景下的数据一致性问题?今天冰河的分布式锁服务插件mykit-lock开源啦
    在Android Studio中连接字符串之前添加@SuppressLint(“settexti18n”)注释
  • 原文地址:https://blog.csdn.net/zhangtingxiqwq/article/details/133148959