zoukankan      html  css  js  c++  java
  • agc027E

    题目大意

    题解

    长的有点像agc030E实际上没有任何关系,仔细地xjb玩了一两天

    正难则反,考虑一个串每次把a->bb,b->aa能变成什么,把相同长度的分为一层

    a->bb

    b->aa

    aa->bba,abb

    ab->aaa,bbb

    ba->aaa,bbb

    bb->aab,baa

    ……

    首先可以归纳得到一个结论:一个非ab交替的串通过操作一定可以变成a,b,ab,ba四个中的某几个

    然后根据观察可以发现,把a看作+1b看作-1,一个串在操作过程中的值模3不变

    进一步观察可以发现,一个串最后变成什么取决于它的值,为0是ab,ba,为1是a,为2是b

    考虑如何判定一个串T,把T的每个字母扩展成一个串,把这些串拼成S,如果能拼出来则可以,注意一个字母不能扩展成ab交替串

    想过把a->bb之后再扩展,但实际上扩展出来的两个串合在一起可以用b来表示,所以没有必要


    那么考虑如何计数,设f[i]表示S[1,i]的答案,枚举j满足[j+1,i]的值等于枚举放的字母,并且不是ab交替

    这样显然会算重,也显然的可以根据套路只从后往前第一个满足的转移

    有一些思考:当j,k(j<k)都能转移到i时,[j+1,k]的值为0

    转移的前提条件时f[j]是f[k]的子集,但如果[j+1,k]是ab交替串怎么办?

    可以发现每次接上去的串值≠0,因此j不会直接更新到k,而是存在x->j,y->k,手玩一下可以发现x->k是可以的并且等价与x->j且[x+1,y]不是ab交替串,所以直接k->i

    但是有特殊情况,当S串的头是ab交替的时候不满足上面的,即应该从[1,i-1]->i,特判一下即可

    用辅助数组转移即可做到O(n)

    code

    #include <bits/stdc++.h>
    #define fo(a,b,c) for (a=b; a<=c; a++)
    #define fd(a,b,c) for (a=b; a>=c; a--)
    #define add(a,b) a=((a)+(b))%1000000007
    #define mod 1000000007
    #define ll long long
    //#define file
    using namespace std;
    
    int b[100001],c[100001],n,i,j,k,l,ls;
    char a[100002];
    ll f[100001],g[100001],F[100001][3];
    
    int main()
    {
    	#ifdef file
    	freopen("agc027e.in","r",stdin);
    	#endif
    	
    	scanf("%s",a+1),n=strlen(a+1);
    	fo(i,1,n) b[i]=(b[i-1]+((a[i]=='a')?1:-1)+3)%3,c[i]=c[i-1]+(a[i]!=a[i+1]);
    	
    	ls=0;
    	fo(i,1,n)
    	{
    		fo(j,0,2) F[i][j]=F[i-1][j];
    		if (a[i-1]==a[i]) ls=i-1;
    		
    		if (i>1 && (b[i-1]+1)%3==b[i]) add(f[i],g[i-1]);
    		else
    		add(f[i],F[ls][(b[i]+2)%3]);
    		if (b[i]==1 && (c[i-1]!=i-1 || i==1)) add(f[i],1);
    		
    		if (i>1 && (b[i-1]+2)%3==b[i]) add(f[i],g[i-1]);
    		else
    		add(f[i],F[ls][(b[i]+1)%3]);
    		if (b[i]==2 && (c[i-1]!=i-1 || i==1)) add(f[i],1);
    		
    		if (c[i-1]==i-1) g[i]=(i+1)/2,f[i]=1; else g[i]=f[i];
    		F[i][b[i]]=g[i];
    	}
    	printf("%lld
    ",f[n]);
    	
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    Vue--vue-Router
    Vue--vue中的组件、组件绑定事件和数据、私有组件、子组件,父子组件参数互传
    CF 631C report
    生日Party 玄学多维DP
    HDU-6376 度度熊剪纸条
    CF 1012C Dp
    CF 997A
    HDU-1051 一个DP问题
    偶尔间看到,来开心一下
    合并石子
  • 原文地址:https://www.cnblogs.com/gmh77/p/13721577.html
Copyright © 2011-2022 走看看