计数组合数价值序列

Posted 行码棋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了计数组合数价值序列相关的知识,希望对你有一定的参考价值。

题目链接:

https://ac.nowcoder.com/acm/contest/23481/B


本题不要计算序列a的价值,因为从这个方面考虑很难做出来。
应该从取序列中的哪些值才能使序列a的价值不变来考虑。

对于三个数来讨论:

  • a i < a j < a k a_i < a_j <a_k ai<aj<ak a i > a j > a k a_i >a_j>a_k ai>aj>ak
    删除中间的数,序列的价值不会变化。如果中间相同的数有k个,情况数为 2 k 2^k 2k
  • a i < a j > a k a_i < a_j >a_k ai<aj>ak a i > a j < a k a_i >a_j<a_k ai>aj<ak
    删除中间的值,序列价值会发生变化,所以不能删除。但是如果中间的值有多个相等的话,要至少留一个值即可。如果相等数的个数为k,则情况数为 2 k − 1 2^k-1 2k1(去除为空的情况)

接下来,就是对中间的相同的数进行讨论了

把相等的数看成一个连通块,设为 [ i , j ] [i,j] [i,j]

  • 如果满足 a i − 1 < a i = . . . = a j < a j + 1 a_i-1<a_i=...=a_j<a_j+1 ai1<ai=...=aj<aj+1 a i − 1 > a i = . . . = a j > a j + 1 a_i-1>a_i=...=a_j>a_j+1 ai1>ai=...=aj>aj+1(且要满足 i > 1 , j < n i>1,j<n i>1,j<n),则区间 [ i , j ] [i,j] [i,j]的数可以全部删除,不影响价值,这样的区间对答案贡献有 2 j − i + 1 2^j-i+1 2ji+1种方案。
  • 否则区间 [ i , j ] [i,j] [i,j]的数必须保留一个,这样的区间对答案贡献 2 j − i + 1 − 1 2^j-i+1-1 2ji+11 种方案。把所有区间的贡献连乘起来就是答案。

#include<bits/stdc++.h>
using namespace std;

using ll = long long;
const int N = 1e5 + 5, mod = 998244353;

vector<ll> fac(N);
void solve()

	int n;
	cin >> n;
	vector<int> a(n);
	for(auto &i : a) cin >> i;
	
	ll res = 1;
	for(int i = 0, j = 0; i < n; i++)	
	
		j = i;
		while(j < n - 1 && a[j + 1] == a[i]) j++;
		
		if(i - 1 >= 0 and j + 1 < n and (a[i - 1] < a[i] && a[i] < a[j + 1] || a[i - 1] > a[i] && a[i] > a[j + 1]))
			res = res * fac[j - i + 1] % mod;
		else res = res * (fac[j - i + 1] - 1) % mod;
		i = j;
	
	cout << res << "\\n";


int main()

	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	
	fac[0] = 1;
	for(int i = 1; i < N; i++) 
		fac[i] = fac[i - 1] * 2 % mod;
	int t;
	cin >> t;
//	t = 1;
	while(t--) solve();
	return 0;



以上是关于计数组合数价值序列的主要内容,如果未能解决你的问题,请参考以下文章

bzoj4517[Sdoi2016]排列计数 组合数+乘法逆元+dp

错位+组合排列计数

[SDOI2016] 排列计数 (组合数学)

特殊计数序列——第二类斯特林(stirling)数

特殊计数序列——第一类斯特林(stirling)数

[CSP-S模拟测试]:简单的括号序列(组合数)