Solution - P1370 Charlie的云笔记序列

神犇 LEMON_dasiy 推荐的题目,果然做不出来

思路

首先定义状态 \(f_i = \sum_{j = 1}^{i} F(i,j)\)。显然 \(f_1 = 2\)(取 \(a_1\)\(\emptyset\))。

然后,假设没有重复的元素,那么就有组合和单干两种选择。

  • 组合:和前面的选择有关,有 \(2f_{i-1}\) 种选择(选或不选当前元素);
  • 单干:取 \(a_i\)\(\emptyset\)

但是现实是,有重复。但对于一个给定的 \(a_i\),只会重复 \(dp_k+1\) 项,\(k\) 是最近的和 \(a_i\) 一样的元素。

然后求出 \(\sum dp\)。没了。

代码

#include <bits/stdc++.h>
#define rint register int
#define rllong register long long
#define llong long long
#define N 100005
using namespace std;

const int mod = (119<<23)+1;
int dp[N], lst[N];
int a[N], tmp[N], n2;
int n, ans;

int main(){
	scanf("%d", &n);
	for(rint i = 1; i <= n; ++i)
		scanf("%d", &a[i]), tmp[i] = a[i];
	sort(tmp+1, tmp+n+1), n2 = unique(tmp+1, tmp+n+1)-tmp-1;
	for(rint i = 1; i <= n; ++i) a[i] = lower_bound(tmp+1, tmp+n2+1, a[i])-tmp;
	dp[1] = ans = 2, lst[a[1]] = 1;
	for(rint i = 2; i <= n; ++i){
		dp[i] = (dp[i-1]*2+2)%mod;
		if(lst[a[i]]) dp[i] = ((dp[i]-dp[lst[a[i]]-1]-1)%mod+mod)%mod;
		ans = (ans+dp[i])%mod;
		lst[a[i]] = i;
	}
	printf("%d", ans);
	return 0;
}

posted @ 2025-04-19 12:09  Hootime  阅读(10)  评论(0)    收藏  举报