URAL Palindromic Contest
A. Non-palidromic cutting
考虑无解的情形:只能是形如$aaaaa$、$aaabaaa$、$abababa$这三种情况。
有解时,对于最小划分,答案必定是$1$或者$2$,判断整个串是否是回文串即可。
对于最大划分,设$f[i]$表示前$i$个字符的最大划分,则$f[i]=\max(f[j]+1)$,其中$[j+1,i]$有解,这里将限制放宽是因为放宽后最优解不会变化,且条件更加好判断。
可行的$j$可以根据$aaaaa$、$abababa$分奇偶得出两个上界,对于$aaabaaa$,最多只有一个$j$不可行,因此DP的同时分奇偶维护出前缀最大值和次大值即可$O(1)$转移。
时间复杂度$O(n)$。
#include<cstdio>
#include<cstring>
const int N=200010;
int n,i,j,k,x,y,f[N],g[N],dp[N],pre[N][2][2];char a[N];
inline void umin(int&a,int b){a>b?(a=b):0;}
inline void umax(int&a,int b){a<b?(a=b):0;}
inline int max(int a,int b){return a>b?a:b;}
bool checkNO(){
//aaaaa
if(f[n]<=1)return 1;
//aaaabaaaa
if(n&1){
//aaaabaaaa
int m=(n+1)/2;
if(f[n]==m+1&&f[m-1]<=1&&a[1]==a[n])return 1;
//ababababababa
if(g[n]<=1&&g[n-1]<=2)return 1;
}
return 0;
}
int calmin(){
for(int i=1;i<=n;i++)if(a[i]!=a[n-i+1])return 1;
return 2;
}
int main(){
scanf("%s",a+1);
n=strlen(a+1);
for(i=1;i<=n;i++){
f[i]=g[i]=i;
if(i>1&&a[i]==a[i-1])f[i]=f[i-1];
if(i>2&&a[i]==a[i-2])g[i]=g[i-2];
}
if(checkNO())return puts("-1"),0;
for(x=0;x<2;x++)for(y=0;y<2;y++)pre[0][x][y]=-N;
pre[0][0][0]=0;
for(i=1;i<=n;i++){
dp[i]=-N;
j=f[i]-2;
if(j>=0)dp[i]=pre[j][i&1][0]+1;
umin(j,max(g[i],g[i-1]-1)-1);
k=-N;
if(f[i]>2)if(i-f[i]<=f[i]-2-f[f[i]-2]&&a[i]==a[f[i]-2])k=dp[i-((i-f[i]+1)*2+1)];
if(j>=0){
if(pre[j][i&1^1][0]==k)umax(dp[i],pre[j][i&1^1][1]+1);
else umax(dp[i],pre[j][i&1^1][0]+1);
}
for(x=0;x<2;x++)for(y=0;y<2;y++)pre[i][x][y]=pre[i-1][x][y];
if(dp[i]>pre[i][i&1][0])pre[i][i&1][1]=pre[i][i&1][0],pre[i][i&1][0]=dp[i];
else umax(pre[i][i&1][1],dp[i]);
}
printf("%d %d",calmin(),dp[n]);
}
B. 100500 palidnromes
考虑DP,对于每个位置为结尾的回文串的长度可以划分为$O(\log n)$个等差数列,分别转移即可。
时间复杂度$O(n\log n)$。
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=300010;
char s[N];int d[N][2],f[N][2];
struct P{
int d[3];
P(){}
P(int a,int b,int c){d[0]=a;d[1]=b;d[2]=c;}
int&operator[](int x){return d[x];}
}a[32],b[32],c[32];
inline void up(int f[][2],int x,int y){
if(y<=0)return;
int p=y&1;
if(f[x][p]<0)f[x][p]=y;else f[x][p]=min(f[x][p],y);
}
inline void make(int f[][2],int x,int y){if(y>0)f[x][y&1]=y;}
void MinPalindromeSpilt(char*s){
int n=strlen(s);
memset(a,0,sizeof a);
memset(b,0,sizeof b);
memset(c,0,sizeof c);
memset(d,0,sizeof d);
memset(f,0,sizeof f);
for(int i=0;i<=n;i++)d[i][0]=1000000000,d[i][1]=1000000001;
for(int ca=0,j=0;j<n;j++){
int cb=0,cc=0,r=-j-2;
for(int u=0;u<ca;u++){
int i=a[u][0];
if(i>=1&&s[i-1]==s[j])a[u][0]--,b[cb++]=a[u];
}
for(int u=0;u<cb;u++){
int i=b[u][0],d=b[u][1],k=b[u][2];
if(i-r!=d){
c[cc++]=P(i,i-r,1);
if(k>1)c[cc++]=P(i+d,d,k-1);
}else c[cc++]=P(i,d,k);
r=i+(k-1)*d;
}
if(j>=1&&s[j-1]==s[j])c[cc++]=P(j-1,j-1-r,1),r=j-1;
c[cc++]=P(j,j-r,1),ca=0;
P&h=c[0];
for(int u=1;u<cc;u++){
P&x=c[u];
if(x[1]==h[1])h[2]+=x[2];else a[ca++]=h,h=x;
}
a[ca++]=h;
if((j+1)%2==0)f[j+1][0]=j+1,f[j+1][1]=1000000001;
else f[j+1][0]=1000000000,f[j+1][1]=j+1;
for(int u=0;u<ca;u++){
int i=a[u][0],e=a[u][1],k=a[u][2];
r=i+(k-1)*e;
up(f,j+1,f[r][0]+1),up(f,j+1,f[r][1]+1);
if(k>1)up(f,j+1,d[i+1-e][0]),up(f,j+1,d[i+1-e][1]);
if(i+1-e>=0){
if(k>1)up(d,i+1-e,f[r][0]+1),up(d,i+1-e,f[r][1]+1);
else make(d,i+1-e,f[r][0]+1),make(d,i+1-e,f[r][1]+1);
}
}
}
}
int main(){
scanf("%s",s);
MinPalindromeSpilt(s);
int n=strlen(s);
for(int i=1;i<=n;i++){
int x=f[i][1],y=f[i][0];
if(x<1||x>N)x=-1;
if(y<1||y>N)y=-2;
printf("%d %d\n",x,y);
}
}
C. Not common palindromes
将两个串插入同一棵Palindromic Tree然后统计次数即可。
时间复杂度$O(n\log n)$。
#include<cstdio>
const int N=400010,S=26;
int Case,cas,i,j,all,son[N][S],fail[N],cnt[N][2],len[N],text[N],last,tot,ans[3];char s[N];
inline int newnode(int l){
for(int i=0;i<S;i++)son[tot][i]=0;
cnt[tot][0]=cnt[tot][1]=0,len[tot]=l;
return tot++;
}
inline int getfail(int x){
while(text[all-len[x]-1]!=text[all])x=fail[x];
return x;
}
inline void add(int w,int p){
text[++all]=w;
int x=getfail(last);
if(!son[x][w]){
int y=newnode(len[x]+2);
fail[y]=son[getfail(fail[x])][w];
son[x][w]=y;
}
cnt[last=son[x][w]][p]++;
}
int main(){
scanf("%d",&Case);
for(cas=1;cas<=Case;cas++){
newnode(0),newnode(-1);
text[0]=-1,fail[0]=1;
scanf("%s",s);
for(i=0;s[i]>='a';i++)add(s[i]-'a',0);
scanf("%s",s);
for(i=all=last=0;s[i]>='a';i++)add(s[i]-'a',1);
for(i=tot-1;~i;i--){
cnt[fail[i]][0]+=cnt[i][0];
cnt[fail[i]][1]+=cnt[i][1];
if(len[i]>0){
if(cnt[i][0]>cnt[i][1])ans[0]++;
if(cnt[i][0]==cnt[i][1]&&cnt[i][0])ans[1]++;
if(cnt[i][0]<cnt[i][1])ans[2]++;
}
}
printf("Case #%d: %d %d %d\n",cas,ans[0],ans[1],ans[2]);
for(last=tot=all=i=0;i<3;i++)ans[i]=0;
}
}
D. Subpalindrome pairs
正反两遍Manacher求出以每个位置为结尾/开头的回文子串个数,然后相乘即可。
时间复杂度$O(n)$。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=600010;
int n,m,i,r,p,f[N];char a[N],s[N];long long v[N],g[N],ans;
void work(){
for(i=1;i<=n;i++)s[i<<1]=a[i],s[i<<1|1]='#';
s[0]='$',s[1]='#',s[m=(n+1)<<1]='@';
for(r=p=0,f[1]=1,i=2;i<m;i++){
for(f[i]=r>i?min(r-i,f[p*2-i]):1;s[i-f[i]]==s[i+f[i]];f[i]++);
if(i+f[i]>r)r=i+f[i],p=i;
}
for(i=0;i<=n+5;i++)v[i]=0;
for(i=2;i<=n*2;i++)v[(i+1)/2]++,v[(i+f[i])/2]--;
for(i=1;i<=n+5;i++)v[i]+=v[i-1];
}
int main(){
scanf("%s",a+1);
n=strlen(a+1);
work();
for(i=0;i<=n+5;i++)g[i]=v[i];
reverse(g+1,g+n+1);
reverse(a+1,a+n+1);
work();
for(i=2;i<=n;i++)ans+=v[i-1]*g[i];
printf("%lld",ans);
}
E. OEIS A216264
限制条件非常强,考虑爆搜打表,用可撤销的回文树快速判断即可。
#include<iostream>
#include<string>
using namespace std;
int n,i;string f[70];
int main(){
f[1]="2";
f[2]="4";
f[3]="8";
f[4]="16";
f[5]="32";
f[6]="64";
f[7]="128";
f[8]="252";
f[9]="488";
f[10]="932";
f[11]="1756";
f[12]="3246";
f[13]="5916";
f[14]="10618";
f[15]="18800";
f[16]="32846";
f[17]="56704";
f[18]="96702";
f[19]="163184";
f[20]="272460";
f[21]="450586";
f[22]="738274";
f[23]="1199376";
f[24]="1932338";
f[25]="3089518";
f[26]="4903164";
f[27]="7728120";
f[28]="12099440";
f[29]="18825066";
f[30]="29112876";
f[31]="44767202";
f[32]="68461866";
f[33]="104153666";
f[34]="157657852";
f[35]="237510110";
f[36]="356158688";
f[37]="531729840";
f[38]="790476048";
f[39]="1170354912";
f[40]="1725978316";
f[41]="2535782098";
f[42]="3711932174";
f[43]="5414527812";
f[44]="7871216066";
f[45]="11405072346";
f[46]="16472995026";
f[47]="23719943936";
f[48]="34053444354";
f[49]="48748102876";
f[50]="69588917894";
f[51]="99071049592";
f[52]="140673083164";
f[53]="199235958260";
f[54]="281479919278";
f[55]="396717767314";
f[56]="557825677390";
f[57]="782576306282";
f[58]="1095448703190";
f[59]="1530103385844";
f[60]="2132734033216";
f[61]="2966632985826";
cin>>n;
for(i=1;i<=n;i++)cout<<f[i]<<endl;
}
URAL Palindromic Contest的更多相关文章
- Ural 1960 Palindromes and Super Abilities
Palindromes and Super Abilities Time Limit: 1000ms Memory Limit: 65536KB This problem will be judged ...
- URAL 1208 Legendary Teams Contest(DFS)
Legendary Teams Contest Time limit: 1.0 secondMemory limit: 64 MB Nothing makes as old as years. A l ...
- Ural State University Internal Contest October'2000 Junior Session
POJ 上的一套水题,哈哈~~~,最后一题很恶心,不想写了~~~ Rope Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7 ...
- ural 1208 Legendary Teams Contest
题意描述:给定K支队伍,每队三个队员,不同队伍之间队员可能部分重复,输出这些队员同时能够组成多少完整的队伍: DFS,利用DFS深度优先搜索,如果该队所有队员都没有被访问过,那么将该队计入结果,再去选 ...
- Petrozavodsk Summer-2016. Ural FU Dandelion Contest
A. Square Function 留坑. B. Guess by Remainder 询问$lcm(1,2,3,...,n)-1$即可一步猜出数. 计算$lcm$采用分治FFT即可,时间复杂度$O ...
- ural 2071. Juice Cocktails
2071. Juice Cocktails Time limit: 1.0 secondMemory limit: 64 MB Once n Denchiks come to the bar and ...
- ural 2073. Log Files
2073. Log Files Time limit: 1.0 secondMemory limit: 64 MB Nikolay has decided to become the best pro ...
- ural 2070. Interesting Numbers
2070. Interesting Numbers Time limit: 2.0 secondMemory limit: 64 MB Nikolay and Asya investigate int ...
- ural 2069. Hard Rock
2069. Hard Rock Time limit: 1.0 secondMemory limit: 64 MB Ilya is a frontman of the most famous rock ...
随机推荐
- 计蒜客31452 Supreme Number(找规律)
A prime number (or a prime) is a natural number greater than 11 that cannot be formed by multiplying ...
- 史上最简单的SpringCloud教程 | 第二篇: 服务消费者(rest+ribbon)
在上一篇文章,讲了服务的注册和发现.在微服务架构中,业务都会被拆分成一个独立的服务,服务与服务的通讯是基于http restful的.Spring cloud有两种服务调用方式,一种是ribbon+r ...
- excel 中怎么让两列姓名相同排序(转)
如图,A列B列不动,C列和D列行值不变,以A列姓名为主让C列姓名和A列相同姓名的对齐(行),D行跟着C行不变. 在E1输入公式=MATCH(C1,A:A,0)然后下拉,接著选中C,D,E列,以E列为标 ...
- echo的运行
例子:编译.链接examples中的echo. 编译: g++ -c -I ~/build/release-install-cpp11/include echo.cc -std=c++11 g++ - ...
- VS2015 生成事件 命令参数
来源:https://stackoverflow.com/questions/11001822/copy-files-from-one-project-to-another-using-post-bu ...
- .NetCore 下开发独立的(RPL)含有界面的组件包 (四)授权过滤
.NetCore 下开发独立的(RPL)含有界面的组件包 (一)准备工作 .NetCore 下开发独立的(RPL)含有界面的组件包 (二)扩展中间件及服 务 .NetCore 下开发独立的(RPL)含 ...
- webpack学习笔记--多种配置类型
除了通过导出一个 Object 来描述 Webpack 所需的配置外,还有其它更灵活的方式,以简化不同场景的配置. 下面来一一介绍它们. 导出一个 Function 在大多数时候你需要从同一份源代码中 ...
- jQuery中的extend()方法
通常我们使用jquery的extend时,大都是为了实现默认字段的覆盖,即若传入某个字段的值,则使用传入值,否则使用默认值.如下面的代码: function getOpt(option){ var _ ...
- JAVA-ORM框架整理➣Mybatis操作MySQL
概述 在Java中,对数据库操作的框架很多,上节概述Hibernate的简单使用,这里简单整理Mybatis的使用.Mybatis也是简单的数据库操作框架,通过IOC方式,获取操作类对象,进行数据的操 ...
- xcode svn commit is not under version control 和 git常用指令
使用Xcode提交一个第三方库时,由于包含资源文件,总是提交不了,提示报错:XXX commit is not under version control (1) 网上查了下,得知 xcode对于sv ...