CF1750F Majority
看到这个题目觉得非常神奇。
首先我们考虑设表示长度的答案,但是显然不好转移。
考虑容斥,用总方案数减去不能消成一个的方案数,这里的总方案数要求两端都是黑的,也就是。
考虑一个不能弄成全的最终状态长什么样,应该是段,奇数段为黑,偶数段为白,且每个白段的长度都大于两侧的黑段长度之和。
为此可以设计一个dp:设表示前面总共有个,最后以黑段结尾,且黑段长度为的方案数。表示前面总共有个,最后以白段结尾,且白段减前面的黑段长度为的方案数。
可以发现转移的形式是前缀和,可以优化到
code:
#include<bits/stdc++.h>
#define Gc() getchar()
#define Me(x,y) memset(x,y,sizeof(x))
#define Mc(x,y) memcpy(x,y,sizeof(x))
#define d(x,y) ((m)*(x-1)+(y))
#define R(n) (rnd()%(n))
#define Pc(x) putchar(x)
#define LB lower_bound
#define UB upper_bound
#define PB push_back
using ll=long long;using db=double;using lb=long db;using ui=unsigned;using ull=unsigned ll;
using namespace std;const int N=5e3+5,M=100+5,K=(1<<10)+5,mod=1e9+7,Mod=mod-1;ll INF=1e18+7;const db eps=1e-5;mt19937 rnd(time(0));
int n,p;ll f[N][N][2],Po[N],g[N],Q[N][N][2];
int main(){
freopen("1.in","r",stdin);
int i,j,h;scanf("%d%d",&n,&p);for(Po[0]=i=1;i<=n;i++) Po[i]=Po[i-1]*2%p;
for(i=1;i<=n;i++){g[i]=(i^1?Po[i-2]:1);
for(j=1;j<i;j++){
//for(h=j+1;h<=i-j;h++) f[i][j][0]=(f[i-j][h][1]*g[j]+f[i][j][0])%p;
f[i][j][0]=g[j]*Q[i-j][j+1][1]%p;
}
for(j=1;j<i;j++){
//for(h=j+1;h<=i;h++) f[i][j][1]=(f[i-h][h-j][0]+f[i][j][1])%p;
f[i][j][1]=Q[i-(j+1)][1][0];
}
for(j=0;j<=i;j++) g[i]-=f[i][j][0];for(j=1;i-j>j;j++) f[i][i-2*j][1]+=g[j];g[i]=(g[i]%p+p)%p;
for(j=i;j;j--) Q[i][j][1]=(Q[i][j+1][1]+f[i][j][1])%p,Q[i][j][0]=(Q[i-1][j+1][0]+f[i][j][0])%p;
}printf("%lld\n",g[n]);
}
分类:
CodeForces
标签:
dp
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
2021-11-14 LOJ #6041. 「雅礼集训 2017 Day7」事情的相似度