AtCoder Grand Contest 043

题外话,好像这场的题都比较牛逼(好多题idea都是出自这场的)

A - Range Flip Find Route

题意:

相当于是每一次操作可以使得一个子矩阵翻转一下

sol.其实挺好想的,如果我们一段走的都是\(.\),那么不用转就可以了,那么如果一段走的都是\(*\),那么直接把走的这个路径所框出来的子矩阵全部翻转掉就好了

其实就是相当于最小化:\(\{一次移动的两个格子颜色不同的次数\}\)

B - 123 Triangle

题意:

sol.

先手玩一下样例

1231
112
01
1

1.可能出现的只有0,1,2,3,且3只能出现在第一层

2.有1,那答案就必须是1

3.否则答案为0/2,考虑杨辉三角于其意义即可

C - Giant Graph

sol.之前暑假的时候打过,是一个FWT+SG函数的题目

之后找到之前写的东西再贴

D - Merge Triplets

题意:

sol.相当于是:划分成n/3个集合,规定其中出现的先后顺序,问出来的方案数

如果后面有一个数要放并且比它 大 直接放即可
如果后面放的这个数比 它小 一定是在它的后面

但这些结论还不够强,每个数放的顺序不太好确定

好了,打摆了(只擅长数据结构实锤了)

没事了,原来是分析一下 排列的构造性质就可以做掉了艹

1:单调连续递减长度 < 3
2: 单调连续递减 = 1 >= 单调连续递减 = 2

上述为该排列的充分必要条件(等价)

#include<bits/stdc++.h>
#define MAXN 20005
typedef long long ll;
using namespace std;

/*
1:单调连续递减长度 < 3
2: 单调连续递减 = 1 >= 单调连续递减 = 2 
*/

int n;
ll mod , f[MAXN][MAXN];

int main(){
	scanf("%d%lld" , &n , &mod);
	n = n * 3;
	f[0][n] = 1;
	for(ll i = 0 ; i < n ; i++){
		for(int j = -i ; j <= i ; j++){
			f[i + 1][j + n + 1] = (f[i + 1][j + n + 1] + f[i][j + n]) % mod;
			f[i + 2][j + n - 1] = (f[i + 2][j + n - 1] + f[i][j + n] * (i + 1ll)) % mod;
			f[i + 3][j + n] = (f[i + 3][j + n] + f[i][j + n] * (i + 1) * (i + 2ll)) % mod; 
		}
	}
	ll ans = 0;
	for(int j = 0 ; j <= n ; j++)ans = (ans + f[n][j + n]) % mod;
	cout<<ans<<endl;
}
posted @ 2021-11-03 21:44  After_rain  阅读(52)  评论(0)    收藏  举报