zoukankan      html  css  js  c++  java
  • codeforces291E Tree-String Problem

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作。

    本文作者:ljh2000
    作者博客:http://www.cnblogs.com/ljh2000-jump/
    转载请注明出处,侵权必究,保留最终解释权!

    题目链接:codeforces291E

    正解:哈希+倍增

    解题报告:

      突然发现我似乎搞复杂了…

      不管了,先讲一讲我的做法好了。

      因为字符最多只有$3*10^5$个,那么把字符拆成一个个点,构出一张新图,又因为题目中有限制,必须是一条从上往下的路径,

      所以对于每个点都考虑以当前点为结尾的字符串是否与要求的相同,这个的话$hash$就可以了,

      然后取出一段祖先区间就用倍增维护好了。

      做法暴力,好写好想…

    //It is made by ljh2000
    //有志者,事竟成,破釜沉舟,百二秦关终属楚;苦心人,天不负,卧薪尝胆,三千越甲可吞吴。
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <ctime>
    #include <vector>
    #include <queue>
    #include <map>
    #include <set>
    #include <string>
    #include <complex>
    #include <bitset>
    using namespace std;
    typedef long long LL;
    typedef long double LB;
    typedef complex<double> C;
    const double pi = acos(-1);
    const int MAXN = 600011;
    const int MAXM = 1200011;
    const int mod = 52013147;
    const int base = 29;
    int n,m,tot,ecnt,father[MAXN],first[MAXN],to[MAXM],next[MAXM],f[MAXN][20],deep[MAXN],ans;
    LL mo[MAXN],g[MAXN][20],Ha;
    char s[MAXN];
    inline void link(int x,int y){ next[++ecnt]=first[x]; first[x]=ecnt; to[ecnt]=y; }
    inline int getint(){
        int w=0,q=0; char c=getchar(); while((c<'0'||c>'9') && c!='-') c=getchar();
        if(c=='-') q=1,c=getchar(); while (c>='0'&&c<='9') w=w*10+c-'0',c=getchar(); return q?-w:w;
    }
    
    inline void init(){
    	mo[0]=1; for(int i=1;i<=600000;i++) mo[i]=mo[i-1]*base,mo[i]%=mod;
    	for(int j=1;j<=19;j++)
    		for(int i=1;i<=tot;i++) {
    			f[i][j]=f[f[i][j-1]][j-1];
    			g[i][j]=( g[i][j-1]*mo[(1<<(j-1))] + g[f[i][j-1]][j-1] )%mod;
    		}
    }
    
    inline bool check(int x){
    	LL now=0; int remain=m;
    	for(int i=19;i>=0;i--)
    		if(remain>=(1<<i))
    			now=(now*mo[(1<<i)]+g[x][i])%mod,x=f[x][i],remain-=(1<<i);
    	if(now==Ha) return true;
    	return false;
    }
    
    inline void dfs(int x,int fa){
    	if(deep[x]>=m) {
    		if(check(x)) 
    			ans++;
    	}
    	for(int i=first[x];i;i=next[i]) {
    		int v=to[i]; if(v==fa) continue;
    		deep[v]=deep[x]+1; dfs(v,x);
    	}
    }
    
    inline void work(){
    	n=tot=getint(); int len,last;
    	for(int i=2;i<=n;i++) {
    		father[i]=getint();
    		scanf("%s",s+1); len=strlen(s+1);
    		last=father[i];
    		for(int j=1;j<len;j++) {
    			tot++;
    			f[tot][0]=last;
    			g[tot][0]=s[j]-'a'+1;
    			link(last,tot);
    			last=tot;
    		}
    		link(last,i);
    		f[i][0]=last;/*!!!*/
    		g[i][0]=s[len]-'a'+1;
    	}
    	init();
    	scanf("%s",s+1); m=strlen(s+1);
    	Ha=0;
    	for(int i=m;i>=1;i--) Ha=Ha*base+s[i]-'a'+1,Ha%=mod;
    	dfs(1,0);
    	printf("%d",ans);
    }
    
    int main()
    {
        work();
        return 0;
    }
    //有志者,事竟成,破釜沉舟,百二秦关终属楚;苦心人,天不负,卧薪尝胆,三千越甲可吞吴。
    

      

  • 相关阅读:
    php跨平台总结 常用预定义常量
    HDU 2065 "红色病毒"问题 (指数母函数 && 泰勒级数)
    ZOJ 3662 Math Magic (2012 Changchun Regional; LCM,DP)
    HDU 2065 "红色病毒"问题 (指数母函数 && 泰勒级数)
    状态压缩DP棋盘模型总结
    HDU 3033 I love sneakers! (分组背包变形)
    状态压缩DP棋盘模型总结
    ZOJ 3662 Math Magic (2012 Changchun Regional; LCM,DP)
    POJ 2671 Jimmy's Bad Day ★ (区间DP)
    HDU 3033 I love sneakers! (分组背包变形)
  • 原文地址:https://www.cnblogs.com/ljh2000-jump/p/6545439.html
Copyright © 2011-2022 走看看