CF 506E

Description

Input

Output

Sample Input

输入1:add2输入2:xzx0

Sample Output

输出1:28

输出2:1

Data Constraint

首先有一个40分dp的解法, 设f[i][l][r]表示回文串已填了i位,给出串从左边匹配到第l位,右边匹配到第r位的方案数,如果能匹配则强制匹配,这样可以去重。

但对于100%的数据N非常大,自然想到用矩阵乘法快速幂优化。

按照dp的转移我们可以建出一张图。每个点D(l,r)表示原串分别匹配到(l,r)位,那么即可根据dp的转移连边

Eg.

对于add连边如下

这样有S^2级别的点,在图上对于每条路径用矩乘优化依然会超时。

然而我们发现一条路径走就是在每个节点分别的不断自环,不记先后顺序,所以如果两条路径上24环的数量一致,那么它们25环和26环的数量也会一致,对答案的贡献也是一致的,可以一起计算。这样我们可以先用一个dp预处理出24环数为i的路径有多少条。

然而如果对于每条路径都矩乘一次,仍然会超时。我们发现对于两条24环数不同的路径,其中一条可能为另一条的一部分,所以不需要重复计算。

据此我们可以构一张大图,左边都是24点,右边都是25点,每个25点连一个26点,对大图作一次矩乘,然后每条路径只是起点和终点不同而已(例如对于经过1个24,2个25的路径即为3号到8号点的路径)

正常来说这样就能过了,但本题中我们还需要优化矩乘,合理标号我们可以发现,只有编号小的到编号大的点有边,那么这样就可以限制j,k的范围,我们还可以把k放在第二维,减少寻址的耗时。

End.

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<cstring>

using namespace std;

struct Matrix{
    int a[402][402];
};

Matrix ans,d,g,anso,anst;
int mo=10007;
char s[221];
int i,L,n,N,Ans,tot;
int dp[211][2];
int f[211][211][211];

Matrix operator *(Matrix a,Matrix b)
{
    int i,j,k,Tmp;
    Matrix c;
    for(i=1;i<=tot;i++)
        for(j=1;j<=tot;j++)c.a[i][j]=0;
    for(i=1;i<=tot;i++)
        for(k=i;k<=tot;k++)if(a.a[i][k]){
            Tmp=a.a[i][k];
            for(j=k;j<=tot;j++)c.a[i][j]=(c.a[i][j]+Tmp*b.a[k][j])%mo;
        }
    return c;
}

void update(int i,int nl,int nr,int l,int r)
{
    if(nl+1>=nr){
        if(N%2==0)dp[i][0]=(dp[i][0]+f[i][l][r])%mo;
        else{
            if(nl+1==nr)dp[i][0]=(dp[i][0]+f[i][l][r])%mo;
            else dp[i][1]=(dp[i][1]+f[i][l][r])%mo;
        }
    }
    else{
        if(s[nl+1]==s[nr-1])f[i][nl][nr]=(f[i][nl][nr]+f[i][l][r])%mo;
        else f[i+1][nl][nr]=(f[i+1][nl][nr]+f[i][l][r])%mo;
    }
}

void prepare()
{
    int i,j,l,r,nl,nr;
    if(s[1]==s[L])f[0][0][L+1]=1;
    else f[1][0][L+1]=1;
    for(i=0;i<=L;i++)
        for(l=0;l<=L;l++)
            for(r=L+1;r>=l;r--)if(f[i][l][r]){
                if(l+1<=r-1){
                    if(s[l+1]==s[r-1])update(i,l+1,r-1,l,r);
                    else{
                        update(i,l+1,r,l,r);
                        update(i,l,r-1,l,r);
                    }
                }
            }
}

void build()
{
    int i;
    for(i=1;i<=L;i++)d.a[i][i]=24,d.a[i][i+1]=1;
    for(i=1;i<=(L+1)/2;i++){
        tot=L+i;
        if(i!=(L+1)/2)d.a[tot][tot+1]=1;
        d.a[tot][tot]=25;
        d.a[tot][tot+(L+1)/2]=1;
        d.a[tot+(L+1)/2][tot+(L+1)/2]=26;
    }
    tot+=(L+1)/2;
}

void mi(int x)
{
    while(x){
        if(x%2==1)ans=ans*d;
        x/=2;
        d=d*d;
    }
}

void work()
{
    int i,j;
    for(i=1;i<=tot;i++)ans.a[i][i]=1;
    for(i=1;i<=tot;i++)
        for(j=1;j<=tot;j++)g.a[i][j]=d.a[i][j];
    if(N%2==1){
        mi(N/2);
        for(i=1;i<=tot;i++)
            for(j=1;j<=tot;j++){
                d.a[i][j]=g.a[i][j];
                anso.a[i][j]=ans.a[i][j];
            }
        mi(1);
        for(i=1;i<=tot;i++)
            for(j=1;j<=tot;j++){
                anst.a[i][j]=ans.a[i][j];
                ans.a[i][j]=anso.a[i][j];
                d.a[i][j]=g.a[i][j];
            }
        for(i=1;i<=(L+1)/2;i++)d.a[L+i][L+i+(L+1)/2]=0;
        mi(1);
    }
    else mi(N/2);
}

void calc()
{
    int i,ts,tg;
    for(i=0;i<=L;i++){
        dp[i][0]=dp[i][0]%mo;
        dp[i][1]=dp[i][1]%mo;
        ts=i;
        if((L-ts)%2==1)tg=(L+1-ts)/2;
        else tg=(L-ts)/2;
        Ans=(Ans+dp[i][0]*ans.a[L-ts+1][L+tg+(L+1)/2])%mo;
        Ans=(Ans+dp[i][1]*anst.a[L-ts+1][L+tg+(L+1)/2])%mo;
    }
}

int main()
{
    scanf("%s",s+1);
    scanf("%d",&n);
    L=strlen(s+1);
    N=n+L;
    prepare();
    build();
    work();
    calc();
    printf("%d\n",Ans);
}
时间: 2024-11-09 04:53:07

CF 506E的相关文章

微信 {&quot;errcode&quot;:40029,&quot;errmsg&quot;:&quot;invalid code, hints: [ req_id: Cf.y.a0389s108 ]&quot;}

{"errcode":40029,"errmsg":"invalid code, hints: [ req_id: Cf.y.a0389s108 ]"} 问题:微信网页授权后,获取到 openid 了,一刷新又没了 微信网页授权获取到的 code 只能使用一次(5分钟内有效),使用一次后,马上失效. 页面授权跳转成功,根据 code 也换取到 openid 了. 此时刷新页面,并不会再次进行授权,而是直接刷新了一下上一次授权跳转后的链接,带的还是

CF with friends and user&#39;s influence considered on NYC data(updated Aug,11st)

Here is the code link: https://github.com/FassyGit/LightFM_liu/blob/master/U_F1.py I use NYC data as other experimens. The split of the training data was seperated by the timeline, and I have normalised the interaction matrix by replacing the checkin

CF 750

今天CF打的块残废了     就是一废物 A 在24点之前到 直接模拟即可 #include<stdio.h> #include<algorithm> #include<cstring> #include<string> #include<cmath> using namespace std; #define LL long long #define MAXN 1010 #define inf 1000000000.0 int main() {

CF #394 (2) 5/6

Codeforces Round #394 (Div. 2) 总结:有毒的一场比赛.做了三题,结果A被叉,B.C挂综测,还hack失败一发,第一次在CF体会到了-50分的感觉..不知道是不是人品好,比赛时room炸了,然后,unrated.. A  水题,判一下0 0,然后abs(a-b)<=1 B  水题,组个间距比较一下,但一个数的时候要判一下 C  直接暴力上的题 D  也是xjb暴力 题意:给出n,l,r, a[], p[],另有两个数组b[], c[],ci=bi-ai.l<=ai,

一场CF的台前幕后(上)——转

前奏 大约4月份的时候,业界毒瘤pyx噔噔噔跑过来说:“酷爱!我YY了一道题!准备当CF的C” 我当时就被吓傻了."Yet another Chinese round?" “区间取模,区间求和” 感觉这题还不错?不过pyx嫌水了…… 好办!当时我刚刚出完动态仙人掌不久,于是一拍脑袋说:把这个问题出到仙人掌上去! 当然被pyx鄙视了…… 后来一直就没啥动静,直到5月底的CTSC. 试机的时候pyx给我看了套他出的神题……里面有一道题……我不小心读成了下面这个样子: “给定n个m维的模2意

[2016-03-22][CF][69A][Young Physicist]

时间:2016-03-22 19:41:34 星期二 题目编号:[2016-03-22][CF][69A][Young Physicist] 题目大意:判断向量和是否为0 分析:对应坐标相加 遇到的问题:不能用x+y+z来判断是否都为0,除非输入都是正数 #include <cstdio> using namespace std; int main(){ int a,b,c,x,y,z,n; x = y = z = 0; scanf("%d",&n); for(in

ARC下OC对象和CF对象之间的桥接(bridge)

在开发iOS应用程序时我们有时会用到Core Foundation对象简称CF,例如Core Graphics.Core Text,并且我们可能需要将CF对象和OC对象进行互相转化,我们知道,ARC环境下编译器不会自动管理CF对象的内存,所以当我们创建了一个CF对象以后就需要我们使用CFRelease将其手动释放,那么CF和OC相互转化的时候该如何管理内存呢?答案就是我们在需要时可以使用__bridge,__bridge_transfer,__bridge_retained,具体介绍和用法如下

【CF 520D】Cubes

[CF 520D]Cubes 怎么说呢--英语阅读题+超级大模拟-- 最重要的是知道怎么出来的数据...题意好懂 xy坐标内给出几个单位正方形 以正方形左下点坐标给出 y=0为地面 正方形下面或者左右下方至少存在一个正方形他才能稳定.. 正方形按0~m-1标号 每次只能取出不影响整体结构的正方形 甲乙玩一个游戏 交替取正方形 每取下一个按从左到右的顺序排好 得到一个大数 重点来了! 取出的数是m进制 转换为十进制是最终结果 甲希望结果最大 乙希望结果最小 问结果为多少 甲先取 题意明白了模拟就行

cf 148D Bag of mice

The dragon 选一只老鼠,然后会跑掉一只 the princess选一只老鼠,不会跑出另外的老鼠 求the princess赢的概率 1 #include<iostream> 2 #include<string> 3 #include<cstdio> 4 #include<vector> 5 #include<queue> 6 #include<stack> 7 #include<algorithm> 8 #inc