ARC128D

考虑我们直接dp
那么需要快速的求出一段是否可以被消掉只剩两端。
我们可以考虑反过来做的。
我们知道如果全为abab型或者aa型则无法消掉
那么我们要前缀和,以及遇到aa则另起一套,否则我们记录最后一段ababf和。

#include <bits/stdc++.h>

#define in read()
#define fi first
#define se second
#define pb push_back
#define rep(i, x, y) for(int i = (x); i <= (y); i++)
#define per(i, x, y) for(int i = (x); i >= (y); i--)

using namespace std;

using pii = pair < int , int >;
using vec = vector < int >;
using veg = vector < pii >;
using ll = long long;

int read() {
    int x = 0; bool f = 0; char ch = getchar(); while(!isdigit(ch)) f |= ch == '-',ch = getchar();
    while(isdigit(ch)) x = x * 10 + (ch ^ 48),ch = getchar(); return f ? -x : x;
}

const int N = 2e5 + 10;
const int mod = 998244353;

int a[N], s[N], n, f[N];

bool check(int l, int r) {
	if(r > l + 1 && a[l] == a[l + 1]) return 1;
	if(r > l + 1 && a[r] == a[r - 1]) return 1;
	return 0;
}

int pos[N];

int main() {
#ifndef ONLINE_JUDGE
    freopen("1.in","r",stdin);
#endif
    n = in; rep(i, 1, n) a[i] = in;
	int l = 1, ts = 0;
	rep(i, 1, n) {
		if(i == 1) f[i] = 1;
		if(a[i] == a[i - 1]) { l = i, ts = 0; f[i] = f[i - 1]; s[i] = (s[i - 1] + f[i]) % mod; continue; }
		f[i] = (f[i] + s[i - 1] - s[l - 1]) % mod;
		if(i - 3 >= l && a[i] == a[i - 2] && a[i - 1] == a[i - 3]) ts = (ts + f[i - 3]) % mod, f[i] = (f[i] + mod - ts) % mod; else ts = 0;
		f[i] = (f[i] + mod) % mod;
		s[i] = (s[i - 1] + f[i]) % mod;
		cerr << i << " " << l << " " << f[i] << endl;
	}
	printf("%d\n", f[n]); return 0;
}

本文作者:fhq_treap

本文链接:https://www.cnblogs.com/dixiao/p/15416635.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   fhq_treap  阅读(72)  评论(0)    收藏  举报
编辑推荐:
· 如何反向绘制出 .NET程序 异步方法调用栈
· 领域驱动设计实战:聚合根设计与领域模型实现
· 突破Excel百万数据导出瓶颈:全链路优化实战指南
· 如何把ASP.NET Core WebApi打造成Mcp Server
· Linux系列:如何用perf跟踪.NET程序的mmap泄露
阅读排行:
· 聊聊 ruoyi-vue ,ruoyi-vue-plus ,ruoyi-vue-pro 谁才是真正的
· C#开发的Panel滚动分页控件 - 开源研究系列文章
· 如何反向绘制出 .NET程序 异步方法调用栈
· ShadowSql之开源不易
· Python 3.14 新特性盘点,更新了些什么?
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起