AGC 041D

考虑限制一定是对于前缀和后缀的,并且显然相交的前后缀可以不考虑。然后还可以发现只用考虑最长的那一段的条件,即 $\lfloor\frac {n-1}{2}\rfloor$ 和 $\lfloor\frac {n-1}{2}\rfloor + 1$ 的长度。

可以将原序列分成两个部分。

如下: $$ {A A | (C) | B} $$ 我们把 $C$ 去掉,把最后一个 $A$ 提出来。

分别向前后差分分别记为数组 $a,b$ 。发现 $\sum _i (a_i + b_i) * i$ 就是除去 $A$ 的差。

即 $\text{最后一个 A 的值} > \sum _i (a_i + b_i) * i​$ 。

向后的差分还对 $A​$ 的最大值有影响,贡献要多一个。

并且容易发现最后的方案就是 $n - \sum (a_i + b_i)*i + \sum b_i​$, 小于 $0​$ 没有贡献。

然后发现有些时候方案数要多乘一个 $b_i+1$ (有一个 $C$ 在中间),这个也可以轻松统计。

代码

1#include<bits/stdc++.h> 2using namespace std; 3int mod, n; 4typedef long long ll; 5int add(int a,int b){a+=b;return a>=mod?a-mod:a;} 6int sub(int a,int b){a-=b;return a<0?a+mod:a;} 7int mul(int a,int b){return (ll)a*b%mod;} 8int qpow(int a,int b){int ret=1;for(;b;b>>=1,a=mul(a,a))if(b&1)ret=mul(ret,a);return ret;} 9/* math */ 10const int N = 5010; 11int f[2][N],g[2][N],h1[2][N],h2[2][N]; 12 13inline void Do1(int p,int i){ 14 for(int j=0;j<=n;j++)f[i][j] = g[i][j] = h1[i][j] = h2[i][j] = 0; 15 for(int j=0;j<=n;j++){ 16 f[i][j] = add(f[i][j], f[i^1][j]); 17 if(j>=p){ 18 f[i][j] = add(f[i][j], f[i][j-p]); 19 } 20 } 21} 22inline void Do2(int p,int i){ 23 for(int j=0;j<=n;j++)f[i][j] = g[i][j] = h1[i][j] = h2[i][j] = 0; 24 for(int j=0;j<=n;j++){ 25 f[i][j] = add(f[i][j], f[i^1][j]); 26 if(j>=p){ 27 f[i][j] = add(f[i][j], f[i][j-p]); 28 } 29 } 30 for(int j=0;j<=n;j++){ 31 h1[i][j] = add(h1[i][j], 1ll*f[i^1][j]*(j/p-1)%mod); 32 if(j>=p){ 33 h1[i][j] = add(h1[i][j], h1[i][j-p]); 34 } 35 } 36 for(int j=0;j<=n;j++){ 37 f[i][j] = sub(mul(f[i][j], j/p),h1[i][j]); 38 } 39} 40 41int main() 42{ 43 cin >> n >> mod; 44 int _d = (n-1)/2; 45 bool flg=0; 46 if(n%2==0){ flg=1; } 47 int cur = 0; 48 f[cur][0] = 1; 49 for(int i=_d;i;i--){ 50 int p = i; 51 Do1(p,cur^=1); 52 if(i==_d && flg)Do2(p+1,cur^=1); 53 else Do1(p+1,cur^=1); 54 } 55 int ans = 0; 56 if(n==2){cout << 3 << endl;return 0;} 57 for(int i=0;i<=n;i++){ 58 ans = add(ans, mul(f[cur][i], n-i)); 59 } 60 cout << ans << endl; 61}
点赞
收藏

评论区

加载中...

相关推荐

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

java 冒泡排序

思路1.将序列当中的左右元素,依次比较,保证右边的元素始终大于左边的元素;(第一轮结束后,序列最后一个元素一定是当前序列的最大值;)2.对序列当中剩下的n1个元素再次执行步骤1。3.对于长度为n的序列,一共需要执行n1轮比较时间复杂度最佳情况:T(n)O(n)最差情况:T(n)O(n2)平均情

Spring boot在Docker中以JPA方式连接Mysql

背景最近在了解Docker的使用,发现docker在集群部署方面和运维方面有比较大的优势,通过统一的依赖关系,以镜像的方式,将已经打好包的镜像文件,部署到各个节点。如果不用考虑集群的同学,就不用折腾这个,如果想要让应用,有较强的快速部署的能力可以考虑考虑。目标在本机创建两个docker容器,分别为mysql的容器和springbo

HDU 2594(求最长公共前后缀 kmp)

题意是在所给的两个字符串中找最长的公共前后缀,即第一个字符串前缀和第二个字符串后缀的最长相等串。思路是将两个字符串拼接在一起,然后直接套用kmp算法即可。要注意用next会报编译错误,改成Next才过……但next确实不是c关键字。代码如下:!(https://oscimg.oschina.net/oscnet/5

Python递归函数、匿名函数、过滤函数

递归函数Python对递归的深度有限制,超过即会报错。所以一定一要注意跳出条件。斐波拉契数列一个数列,第一个数是1,第二个数也是1,从第三个数开始,每一个数是前两个数之和公式:f(1)1,f(2)1,f(3)f(1)f(2),...,f(n)f(n2)f(n1)

MySQL之索引(四)

压缩索引MyISAM使用前缀压缩来减少索引的大小,从而让更多的索引可以放入内存中,这在某些情况下能极大地提高性能。默认只压缩字符串,但通过参数设置也可以对整数做压缩。MyISAM压缩每个索引块的方法是,先完全保存索引块中的第一个值,然后将其他值和第一个值进行比较得到相同前缀的字节数和剩余的不同后缀部分,把这部分存储起来即可。例如,索引块中的第