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;
}
 
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号