• loj2065 「SDOI2016」模式字符串


    ref不是太懂

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    typedef unsigned long long ull;
    int T, n, m, hea[1000005], cnt, uu, vv, rnd[1000005], rot, siz[1000005];
    int tot, sf[1000005], sg[1000005], ff[1000005], gg[1000005];
    ull bse[1000005], hs1[1000005], hs2[1000005], ans;
    char ss[1000005], tt[1000005];
    bool vis[1000005];
    struct Edge{
    	int too, nxt;
    }edge[2000005];
    void rn(int &x){
    	char ch=getchar();
    	x = 0;
    	while(ch<'0' || ch>'9')	ch = getchar();
    	while(ch>='0' && ch<='9'){
    		x = x * 10 + ch - '0';
    		ch = getchar();
    	}
    }
    void add_edge(int fro, int too){
    	edge[++cnt].nxt = hea[fro];
    	edge[cnt].too = too;
    	hea[fro] = cnt;
    }
    void getRoot(int x, int f){
    	rnd[x] = 0;
    	siz[x] = 1;
    	for(int i=hea[x]; i; i=edge[i].nxt){
    		int t=edge[i].too;
    		if(!vis[t] && t!=f){
    			getRoot(t, x);
    			siz[x] += siz[t];
    			rnd[x] = max(rnd[x], siz[t]);
    		}
    	}
    	rnd[x] = max(rnd[x], tot-siz[x]);
    	if(rnd[x]<rnd[rot])	rot = x;
    }
    int dfs(int x, int f, int d, ull hx){
    	siz[x] = 1;
    	hx = hx * 131 + ss[x];
    	if(hs1[d]==hx){
    		ff[(d-1)%m+1]++;
    		ans += sg[m-(d-1)%m];
    	}
    	if(hs2[d]==hx){
    		gg[(d-1)%m+1]++;
    		ans += sf[m-(d-1)%m];
    	}
    	int tmp=1;
    	for(int i=hea[x]; i; i=edge[i].nxt){
    		int t=edge[i].too;
    		if(!vis[t] && t!=f){
    			siz[x] += siz[t];
    			tmp = max(tmp, dfs(t, x, d+1, hx)+1);
    		}
    	}
    	return tmp;
    }
    void work(int x){
    	vis[x] = true;
    	sf[1] = sg[1] = 1;
    	int tmp=0;
    	for(int i=hea[x]; i; i=edge[i].nxt){
    		int t=edge[i].too;
    		if(!vis[t]){
    			int k=min(m, dfs(t, x, 2, ss[x])+1);
    			tmp = max(tmp, k);
    			for(int j=1; j<=k; j++){
    				sf[j] += ff[j];
    				sg[j] += gg[j];
    				ff[j] = gg[j] = 0;
    			}
    		}
    	}
    	for(int i=1; i<=tmp; i++)
    		sf[i] = sg[i] = 0;
    	for(int i=hea[x]; i; i=edge[i].nxt){
    		int t=edge[i].too;
    		if(!vis[t]){
    			rot = 0;
    			tot = siz[t];
    			getRoot(t, x);
    			work(rot);
    		}
    	}
    }
    int main(){
    	cin>>T;
    	while(T--){
    		rn(n); rn(m);
    		scanf("%s", ss+1);
    		memset(hea, 0, sizeof(int)*(n+1));
    		memset(vis, 0, sizeof(bool)*(n+1));
    		cnt = ans = rot = 0;
    		tot = n;
    		for(int i=1; i<n; i++){
    			rn(uu); rn(vv);
    			add_edge(uu, vv);
    			add_edge(vv, uu);
    		}
    		scanf("%s", tt+1);
    		bse[0] = 1;
    		for(int i=1; i<=n; i++){
    			bse[i] = bse[i-1] * 131;
    			hs1[i] = hs1[i-1] + tt[(i-1)%m+1] * bse[i-1];
    			hs2[i] = hs2[i-1] + tt[m-(i-1)%m] * bse[i-1];
    		}
    		rnd[0] = 0x3f3f3f3f;
    		getRoot(1, 0);
    		work(rot);
    		printf("%llu
    ", ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    基于Delphi的三层数据库系统的实现方法
    用数据表创建树_delphi教程
    多层数据库开发十三:剖析几个数据库应用程序
    多层数据库开发十二:使用数据控件
    多层数据库开发九:查询数据库
    第十一章 TClientDataSet
    用python做线性规划
    Python-sympy科学计算与数据处理(求极限及其它功能)
    Python-sympy科学计算与数据处理(方程,微分,微分方程,积分)
    Python-sympy科学计算与数据处理(数学表达式)
  • 原文地址:https://www.cnblogs.com/poorpool/p/9044815.html
Copyright © 2020-2023  润新知