「PMOI-1」

P7354 「PMOI-1」立方骑士

没意思,分类讨论题

  1. 角落

样例2

  1. 边界

3

  1. 中心(就是除掉上述情况)

4

画一画挺好玩的

和凉心CF一样,NM>=8不需要继续讨论了

P7355 「PMOI-1」抽奖

凉心啊

考虑枚举使用的卡片数,然后我们容斥种类数

t=0mi=0t(ni)(i+1)j=1i(ij)(1)ijjt\sum_{t=0}^m\sum_{i=0}^t*\binom{n}{i}(i+1)*\sum_{j=1}^i\binom{i}{j}(-1)^{i-j}j^t

交换求和符号

1+t=1mj=1t(nj)jti=jt(nij)(1)ij(i+1)1+\sum_{t=1}^m\sum_{j=1}^t\binom{n}{j}j^t*\sum_{i=j}^t\binom{n}{i-j}(-1)^{i-j}(i+1)

推不下去了

算一个卡片的贡献

我们要观察一个事实,就是任意不使用某张卡片方案数都等价

那么总方案数为ntn^t,一种方案数就是nt(n1)tn^t-(n-1)^t,再乘上n就是下式

1+t=1mnt+nt+1(n1)tn1+\sum_{t=1}^m{n^t+n^{t+1}-(n-1)^t*n}

全都是等比数列求和....

这次那个垃圾wolfram终于有反应了

注意n=1和n=2,带入暴力式子即可

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int P = 1e9 + 7;
int T;
ll n, m;

ll ksm(ll x, ll y) {
	ll ans = 1;
	while(y) {
		if(y & 1)ans = ans * x % P;
		x = x * x % P;
		y >>= 1;
	}
	return ans;
}

int main() {
	scanf("%d", &T);
	while(T-- > 0) {
		scanf("%lld%lld", &n, &m);
		if(n == 1) {
			printf("%lld\n", (2 * m + 1) % P);
			continue;
		}
		if(n == 2) {
			printf("%lld\n", ((ksm(n, m + 1) + ksm(n, m + 2) + P - 1 - n) % P * ksm(n - 1, P - 2) % P + P - n * (m + 1) % P) % P);
			continue;
		}
		printf("%lld\n", ((P
						   - n * ksm((n - 2) * (n - 1) % P, P - 2) % P
						   * ((ksm(n, m + 1)
							   - ksm(n, m + 2)
							   + 2 * ksm(n, m) % P
							   + n * n % P * ksm(n - 1, m) % P
							   - 2 * n % P * ksm(n - 1, m) % P
							   + ksm(n - 1, m)
							   + n - 3) % P) % P) + 1) % P);
	}
	return 0;
}

P7356 「PMOI-1」游戏

这种分类讨论题....出题人有视频

第一步走(3,0)(3,0),黄金必胜位

然后黑走(1,0),白走(4,0),三步杀

黑走(2,0),白走(2,2)形成两个[黑空白],下一步无论黑棋放在竖着的还是斜着的都是绝杀

黑走(4,0),白走(2,2),斜着两个[黑空白],下一步黑棋无论放在哪个斜着的都是两步绝杀

写的时候一定要严谨.....被随机下棋的傻子恶心了

#include<bits/stdc++.h>
using namespace std;
int T, x, y;
int main() {
	cin >> T;
	while(T-- > 0) {
		cout << "3 0" << endl;
		cin >> x >> y;
		if(x == 1 && y == 0) {
			cout << "4 0" << endl;
			cin >> x >> y;
			if(x == 2 && y == 0)cout << "5 0" << endl;
			else cout << "2 0" << endl;
		} else if(x == 2 && y == 0) {
			cout << "2 2" << endl;
			cin >> x >> y;
			if(x == 2) {
				cout << "3 3" << endl;
				cin >> x >> y;
				if(x == 1 && y == 1)cout << "4 4" << endl;
				else cout << "1 1" << endl;
			} else {
				cout << "2 3" << endl;
				cin >> x >> y;
				if(y == 1 && x == 2)cout << "2 4" << endl;
				else cout << "2 1" << endl;
			}
		} else if(x == 4 && y == 0) {
			cout << "2 2" << endl;
			cin >> x >> y;
			if(x == y) {
				cout << "1 3" << endl;
				cin >> x >> y;
				if(x == 3 && y == 1)cout << "0 4" << endl;
				else cout << "3 1" << endl;
			} else {
				cout << "3 3" << endl;
				cin >> x >> y;
				if(x == 1 && y == 1)cout << "4 4" << endl;
				else cout << "1 1" << endl;
			}
		} else {
			cout << "2 0" << endl;
			cin >> x >> y;
			if(x == 1 && y == 0)cout << "4 0" << endl;
			else cout << "1 0" << endl;
		}
		cout << endl;
	}
	return 0;
}