https://vjudge.net/problem/TopCoder-15135

之前做过:本质不同的回文子序列个数

本题:位置不同即为不同。

如果还是设$f[l][r]$表示$l$,$r$结尾,就难受了。转移就已经是$O(n^2)$了

所以,$f[l][r]$表示,$[l,r]$的回文子序列个数

$f[l][r]=f[l+1][r]+f[l][r-1]-f[l+1][r-1]+(a[l]==a[r])*(f[l+1][r-1]+1)$

一个区间DP

但是要循环1e9次

但是其实,不管区间长度为多少,一共只有50种取值

所以,f[i][len]表示,扩展到长度为len的区间,[i,i+len-1]的子序列个数

显然i只有50个

然后矩乘转移即可。

100的size,因为还有len-2

#include<bits/stdc++.h>
#define reg register int
#define il inline
#define fi first
#define se second
#define mk(a,b) make_pair(a,b)
#define numb (ch^'0')
#define pb push_back
#define solid const auto &
#define enter cout<<endl
#define pii pair<int,int>
using namespace std;
typedef long long ll;
template<class T>il void rd(T &x){
char ch;x=;bool fl=false;while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
for(x=numb;isdigit(ch=getchar());x=x*+numb);(fl==true)&&(x=-x);}
template<class T>il void output(T x){if(x/)output(x/);putchar(x%+'');}
template<class T>il void ot(T x){if(x<) putchar('-'),x=-x;output(x);putchar(' ');}
template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar('\n');}
namespace Modulo{
const int mod=1e9+;
il int ad(int x,int y){return x+y>=mod?x+y-mod:x+y;}
il int sub(int x,int y){return ad(x,mod-y);}
il int mul(int x,int y){return (ll)x*y%mod;}
il void inc(int &x,int y){x=ad(x,y);}
il void inc2(int &x,int y){x=mul(x,y);}
il int qm(int x,int y=mod-){int ret=;while(y){if(y&) ret=mul(x,ret);x=mul(x,x);y>>=;}return ret;}
template<class ...Args>il int ad(const int a,const int b,const Args &...args) {return ad(ad(a,b),args...);}
template<class ...Args>il int mul(const int a,const int b,const Args &...args) {return mul(mul(a,b),args...);}
}
using namespace Modulo;
const int N=;
int n,m;
struct tr{
int a[N][N];
tr(){memset(a,,sizeof a);}
void init(){
for(reg i=;i<=m;++i){
a[i][i]=;
}
}
tr friend operator *(const tr &a,const tr &b){
tr c;
for(reg k=;k<=m;++k){
for(reg i=;i<=m;++i){
for(reg j=;j<=m;++j){
inc(c.a[i][j],mul(a.a[i][k],b.a[k][j]));
}
}
}
return c;
}
}S,A,B,C;
tr qm(tr A,ll y){
tr ret;
memset(ret.a,,sizeof ret.a);
ret.init();
while(y){
if(y&) ret=ret*A;
A=A*A;
y>>=;
}return ret;
}
class LongPalindromes{
public:
int count(int T,string s){
int n=s.length();
if(n==) return qm(,T);
m=n*;
//0~n-1
//n~m-1
//a[0][m]=1
for(reg i=;i<=n-;++i){
A.a[i][i]=;
A.a[(i+)%n][i]=;
A.a[i][i+n]=;
}
A.a[m][m]=;
B.init();
for(reg len=;len<=n;++len){
C=A;
for(reg i=;i<n;++i){
C.a[(i+)%n+n][i]=sub((s[i]==s[(i+len-)%n]),);
C.a[m][i]=(s[i]==s[(i+len-)%n]);
}
B=B*C;
}
S.a[][m]=;
S=S*qm(B,T);
// printf("%d\n",
return ad(S.a[][],);
}
};

相同的保留一份即可。减少状态。利于矩乘。

TopCoder - 15135 LongPalindromes的更多相关文章

  1. TopCoder kawigiEdit插件配置

    kawigiEdit插件可以提高 TopCoder编译,提交效率,可以管理保存每次SRM的代码. kawigiEdit下载地址:http://code.google.com/p/kawigiedit/ ...

  2. 记第一次TopCoder, 练习SRM 583 div2 250

    今天第一次做topcoder,没有比赛,所以找的最新一期的SRM练习,做了第一道题. 题目大意是说 给一个数字字符串,任意交换两位,使数字变为最小,不能有前导0. 看到题目以后,先想到的找规律,发现要 ...

  3. TopCoder比赛总结表

    TopCoder                        250                              500                                 ...

  4. Topcoder几例C++字符串应用

    本文写于9月初,是利用Topcoder准备应聘时的机试环节临时补习的C++的一部分内容.签约之后,没有再进行练习,此文暂告一段落. 换句话说,就是本文太监了,一直做草稿看着别扭,删掉又觉得可惜,索性发 ...

  5. TopCoder

    在TopCoder下载好luncher,网址:https://www.topcoder.com/community/competitive%20programming/ 选择launch web ar ...

  6. TopCoder SRM 596 DIV 1 250

    body { font-family: Monospaced; font-size: 12pt } pre { font-family: Monospaced; font-size: 12pt } P ...

  7. 求拓扑排序的数量,例题 topcoder srm 654 div2 500

    周赛时遇到的一道比较有意思的题目: Problem Statement      There are N rooms in Maki's new house. The rooms are number ...

  8. TopCoder SRM 590

     第一次做TC,不太习惯,各种调试,只做了一题...... Problem Statement     Fox Ciel is going to play Gomoku with her friend ...

  9. Topcoder Arena插件配置和训练指南

    一. Arena插件配置 1. 下载Arena 指针:http://community.topcoder.com/tc?module=MyHome 左边Competitions->Algorit ...

随机推荐

  1. 基于SSM的RBAC权限系统(1)-利用ajax,bootstrap,ztree完成权限树功能

    仅支持回显以及选择,不支持在树中的编辑 搭建后台回显以及修改的模块 JSON数据封装 public class Msg { private int code; private String msg; ...

  2. PHP之面向对象小结

    PHP 中创建对象 类创建后,我们可以使用 new 运算符来实例化该类的对象: $runoob = new Site; PHP 构造函数 构造函数 ,是一种特殊的方法.主要用来在创建对象时初始化对象, ...

  3. python中的装饰器基本理论

    装饰器 : 本质上 是一个 函数 原则 : 1,不修改原函数的源代码 2,不修改原函数的调用方式. 装饰器的知识储备 装饰器 = 高阶函数 + 函数嵌套 +闭包 我的理解是,函数名也是一个变量,将函数 ...

  4. TypeScript:TypeScript 百科

    ylbtech-TypeScript:TypeScript 百科 TypeScript是一种由微软开发的自由和开源的编程语言.它是JavaScript的一个超集,而且本质上向这个语言添加了可选的静态类 ...

  5. H5rem

    <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1, ...

  6. VUX中selector组件数据错误,value-map不能正常转换接口数据

    项目中有个地方需要用到下拉框,使用VUX的selector组件,使用value-map属性进行接口数据转换未成功,出来的还是原数据 看了又看也没写错呀,字段什么的都是复制上去的,去网上查了也没查到怎么 ...

  7. 【html】 两栏对比网页,同时滚动

    有的时候需要左右对比环境,而且希望能同时滚动,如下这么拼接就可以了 <html> <head><meta http-equiv="content-type&qu ...

  8. VB - 错误处理

    1.最常见的错误是运行时错误,也就是说错误在脚本正在运行的时候发生,是脚本试图进行非法操作的结果.例如零被作为除数.在vbs中,任何运行时错误都是致命的,此时,脚本将停止运行,并在屏幕上显示一个错误消 ...

  9. 48.Course Schedule(课程安排)

    Level:   Medium 题目描述: There are a total of n courses you have to take, labeled from 0 to n-1. Some c ...

  10. SqlServer表名称定义

    每一个数据表 添加一个 扩展 属性:Description  填写表描述. 查看是否所有表都添加的Sql如下: SELECT a.name AS name, g.[value] FROM sys.ta ...