题意

给定$n$个数,重复拼接$m$次,相邻$k$个重复的可消除,问最后序列中有多少个数


首先可以发现当$k>=n$时,如果要使$n$个数可以被消除,那么$n$个数必须一样,否则$n$个数不能被消除

当$k<n$时,首先对序列能够消除的消除,用栈记录每个数和这个数的相同的相邻个数$f$,将序列压缩,考虑一次拼接,记$L$为第二个序列的开始元素,$R$为第一个序列的最后一个元素,如果$L!=R$那么所有序列将不能压缩,如果$LR,f_L+f_R!=k$,那么这两个序列拼接之后会合并成一个不可被消去的元素,减去$m-1$次的贡献得到答案,如果$LR,f_L+f_R==k$,那么这两个可以完全被消除,那么按照相同方式计算$L+1,R-1$对应的贡献,最后如果整个序列都能合并到最后,如果$n$为奇数,表示最后会剩下一个元素,计算这个元素对应答案,如果$n$为偶数,那么答案为$0$

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int st[100100], f[100100];
int n, k, m, a, flag = 0, top = 1;
LL ans = 0;
int main() {
scanf("%d%d%d", &n, &k, &m);
st[0] = 0;
for(int i = 1; i <= n; ++i) {
scanf("%d", &a);
if(st[top - 1] != a) st[top] = a, f[top++] = 1;
else {
if(f[top - 1] + 1 < k) f[top - 1] += 1;
else if(f[top - 1] + 1 == k) top--;
}
}
if(k >= n) {
for(int i = 1; i < top - 1; ++i) if(st[i] != st[i + 1]) flag = 1;
if(!flag) cout << 1LL * n * m % k << endl; else cout << 1LL * n * m << endl;
return 0;
}
for(int i = 1; i < top; ++i) ans += f[i];
if(m == 1 || ans == 0) {cout << ans << endl; return 0;}
ans = 1LL * m * ans;
int L = 1, R = top - 1;
while(L < R) {
if(st[L] != st[R]) {cout << ans << endl; return 0;}
if(f[L] + f[R] == k) {L++; R--;ans -= 1LL * (m - 1) * k; continue;}
if(f[L] + f[R] > k) ans -= 1LL * (m - 1) * k;
cout << ans << endl; return 0;
}
if(L > R) {cout << 0 << endl; return 0;}
if(L == R) {
LL x = 1LL * f[L] * m;
if(x % k == 0) {cout << 0 << endl;}
else {cout << ans - x / (LL)k * (LL)k << endl;}
}
return 0;
}

最新文章

  1. Asp.Net MVC&lt;八&gt;:View的呈现
  2. VB.NET TextBox 只允许输入1-100之间的整数 简洁篇
  3. Laravel 5 性能优化技巧
  4. javascript 红宝书笔记之操作日期
  5. myeclipse 第一个web project
  6. mac osx 启动wireshark闪退
  7. python 批量请求url
  8. Crypto++编译使用
  9. C#扩展方法入门
  10. Oracle全表扫描
  11. Google搜索技术
  12. Codeforces - ZeptoLab Code Rush 2015 - D. Om Nom and Necklace:字符串
  13. 流动python - 自然装饰
  14. 中断MSI INTA
  15. SpringBoot(九):多模块下mapper分散后无法启动SpringBoot解决方法
  16. Linux修改SSH登录端口
  17. OpenSips使用说明
  18. mongodb的优缺点
  19. 使用Unicode字符实现换行
  20. crs_stop 错误一列

热门文章

  1. Android View源码解读:浅谈DecorView与ViewRootImpl
  2. [反汇编练习] 160个CrackMe之030
  3. C#文件路径操作总结【转】
  4. VS中的 MD/MT设置 【转】
  5. Data Binding Guide——google官方文档翻译(上)
  6. C 标准库 - &lt;signal.h&gt;
  7. wince开发_摩托罗拉MC3100_打开条码设置
  8. python(40)- 进程、线程、协程及IO模型
  9. AngularJS 实现 双击排序
  10. 设置Ubuntu 16.04 LTS的Unity启动器的位置命令