zoukankan      html  css  js  c++  java
  • 【清华集训2017模拟12.09】塔

    题目

    有一个塔,他的名字叫做粽粑,粽粑的每一层都有一个颜色 .
    粽粑非常厉害,它在吸收天地精华之后会长高.粽粑的长高方式有两种:
    1.在塔顶长出一层.
    2.在塔底长出一层,即原来的第一层变成第二层,第二层变成第三层,以此类推,新长出来的是第一层.
    粽粑有可能在某个时刻不是很开心,这个时候它会撤销它的前若干次长高.
    你现在想知道粽粑长高的奥秘,于是找到了粽粑,发现它的入口上写着这么一句话:要进入粽粑,请找出一段最长的塔的区间,满足翻转后颜色不变.
    粽粑会不断的长高(或撤销),所以它每次长高后你都要回答.为了你的方便,粽粑一开始的高度为0.

    分析

    我发现我的字符串学傻了⊙﹏⊙‖∣
    回文树模板题,但是卡不过。
    假设上一次的答案为ans,
    对于头尾,我们分别维护长度为ans的字符串的两个哈希值(这个长度为ans的字符串的哈希值高位分别在前或后),
    看哈希值是否一样就能判断是否为回文串。每次长高只会让ans+1或+2,判断一下。

    #pragma GCC optimize(3)
    #include <cmath>
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <map>
    const int maxlongint=2147483647;
    const long long mo=1e9+7;
    const int N=10000005;
    using namespace std;
    int n,m,ans[N],top;
    long long sum[N][4];
    char t[N];
    short int num[N*3];
    long long mi[N],ny,val;
    long long pow1(long long x,int y)
    {
    	long long sum=1;
    	for(;y;x=x*x%mo,y>>=1)
    		if(y&1) sum=sum*x%mo;
    	return sum;
    }
    int main()
    {
    	scanf("%d
    ",&n);
    	ny=pow1(101,mo-2);
    	int l=N,r=l-1;
    	mi[0]=1;
    	for(int i=1;i<=n;i++) mi[i]=mi[i-1]*101%mo;
    	for(int i=1;i<=n;i++)
    	{
    		char c,c1,c2;
    		c=getchar(),c1=getchar(),c2=getchar();
    		int x=((c1-'0')*10+c2-'0'+(ans[top]!=0?ans[top]:0))%100;
    		if(c=='1')
    		{
    			num[++r]=x,t[++top]='1';
    			ans[top]=ans[top-1];
    			sum[top][0]=sum[top-1][0],sum[top][1]=sum[top-1][1],sum[top][2]=sum[top-1][2],sum[top][3]=sum[top-1][3];
    			long long v1=sum[top][0],v2=sum[top][1],len=ans[top];
    			if(len) v1=((v1-mi[len-1]*num[r-len]%mo+mo)*101%mo+num[r])%mo;
    			if(len) v2=((v2-num[r-len]+mo)%mo*ny%mo+mi[len-1]*num[r])%mo;
    			sum[top][0]=v1,sum[top][1]=v2;
    			v1=(v1+mi[len]*num[r-len])%mo;
    			v2=(v2*101+num[r-len])%mo;
    			if(v1==v2)
    			{
    				ans[top]=len+1;
    				sum[top][0]=v1,sum[top][1]=v2;
    				sum[top][2]=(sum[top][2]+mi[len]*num[l+len])%mo;
    				sum[top][3]=(sum[top][3]*101+num[l+len])%mo;
    			}
    			if(r-l+1>=len+2)
    			{
    				v1=(v1+mi[len+1]*num[r-len-1])%mo;
    				v2=(v2*101+num[r-len-1])%mo;
    				if(v1==v2)
    				{
    					ans[top]=len+2;
    					sum[top][0]=v1,sum[top][1]=v2;
    					sum[top][2]=(sum[top][2]+mi[len]*num[l+len])%mo;
    					sum[top][3]=(sum[top][3]*101+num[l+len])%mo;
    					sum[top][2]=(sum[top][2]+mi[len+1]*num[l+len+1]%mo)%mo;
    					sum[top][3]=(sum[top][3]*101+num[l+len+1])%mo;
    				}
    			}
    		}
    		else
    		if(c=='2')
    		{
    			num[--l]=x,t[++top]='0';
    			ans[top]=ans[top-1];
    			sum[top][0]=sum[top-1][0],sum[top][1]=sum[top-1][1],sum[top][2]=sum[top-1][2],sum[top][3]=sum[top-1][3];
    			long long v1=sum[top][2],v2=sum[top][3],len=ans[top];
    			if(len) v1=((v1-mi[len-1]*num[l+len]%mo+mo)*101%mo+num[l])%mo;
    			if(len) v2=((v2-num[l+len]+mo)%mo*ny%mo+mi[len-1]*num[l])%mo;
    			sum[top][2]=v1,sum[top][3]=v2;
    			v1=(v1+num[l+len]*mi[len])%mo;
    			v2=(v2*101+num[l+len])%mo;
    			if(v1==v2)
    			{
    				ans[top]=len+1;
    				sum[top][2]=v1,sum[top][3]=v2;
    				sum[top][0]=(sum[top][0]+mi[len]*num[r-len])%mo;
    				sum[top][1]=(sum[top][1]*101+num[r-len])%mo;
    			}
    			if(r-l+1>=len+2)
    			{
    				v1=(v1+num[l+len+1]*mi[len+1]%mo)%mo;
    				v2=(v2*101+num[l+len+1])%mo;
    				if(v1==v2)
    				{
    					ans[top]=len+2;
    					sum[top][2]=v1,sum[top][3]=v2;
    					sum[top][0]=(sum[top][0]+mi[len]*num[r-len])%mo;
    					sum[top][1]=(sum[top][1]*101+num[r-len])%mo;
    					sum[top][0]=(sum[top][0]+mi[len+1]*num[r-len-1])%mo;
    					sum[top][1]=(sum[top][1]*101+num[r-len-1])%mo;
    				}	
    			}		
    		}
    		else
    		{
    			for(;x--;top--)
    			{
    				if(t[top]=='1') num[r--]=0;
    				else num[l++]=0;
    				sum[top][0]=sum[top][1]=sum[top][2]=sum[top][3]=0;
    			}
    		}
    		val+=1ll*ans[top];
    	}
    	printf("%lld
    ",val);
    }
    
  • 相关阅读:
    python模块--time模块
    python模块--如何相互调用自己写的模块
    Animating Views Using Scenes and Transitions
    fragment 切换
    android textview 设置text 字体
    android intent 5.1
    android EditView ime
    animation of android (4)
    animation of android (3)
    animation of android (2)
  • 原文地址:https://www.cnblogs.com/chen1352/p/9099484.html
Copyright © 2011-2022 走看看