Codeforces Round #752 (Div. 2) ABCD

A. Era

维护一个新数组的末尾位置变量pos,遍历的时候不断更新即可。

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <map>
#include <set>
#define mod 1000000007
//#define mod 998244353
#define ll long long
#define pb push_back
using namespace std;
ll fpow(ll a, ll b) {
	ll ans = 1;
	for(; b; b >>= 1) {
		if(b & 1) ans = ans * a % mod;
		a = a * a % mod;
	}
	return ans;
}
ll gcd(ll a, ll b) {
	return b ? gcd(b, a % b) : a;
}
int a[105], n;
int main() {
	int T = 1;
	cin >> T;
	while(T--) {
		cin >> n;
		for(int i = 1; i <= n; i++) {
			cin >> a[i];
		}
		ll ans = 0;
		a[0] = 0;
		int pos = 1;
		for(int i = 1; i <= n; i++) {
			if(a[i] > pos) {
				ans += a[i] - pos;
				pos += a[i] - pos;
			}
			pos++;
		}
		cout << ans << endl;
	}
	return 0;
}

B. XOR Specia-LIS-t

注意到长度为1的序列也满足单调递增的条件(虽然比较特殊),所以如果n为偶数一定可以(把序列分为n个子数组,每个子数组的最长单调递增子列长度为1,且一共有偶数个);如果n为奇数的话,只要整个序列不是单调递增的话一定可以(把a[i] >= a[i + 1]的这两个数拿出来,其最长递增子序列长度为1,剩下的n - 2个数自己构成一个子数组,这样保证xor和为0),否则不可(因为每个子数组的LCS就是本身,整个序列一定要被划分为若干对,n为奇数显然不可能划分为若干“对”)

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <map>
#include <set>
#define mod 1000000007
//#define mod 998244353
#define ll long long
#define pb push_back
using namespace std;
ll fpow(ll a, ll b) {
	ll ans = 1;
	for(; b; b >>= 1) {
		if(b & 1) ans = ans * a % mod;
		a = a * a % mod;
	}
	return ans;
}
ll gcd(ll a, ll b) {
	return b ? gcd(b, a % b) : a;
}
ll n, a[100005];
int main() {
	int T = 1;
	cin >> T;
	while(T--) {
		cin >> n;
		for(int i = 1; i <= n; i++) {
			cin >> a[i];
		}
		if(n % 2 == 0) puts("YES");
		else {
			bool ok = 0;
			for(int i = 2; i <= n; i++) {
				if(a[i] <= a[i - 1]) {
					ok = 1;
					break;
				}
			}
			if(ok) puts("YES");
			else puts("NO");
		}
	}
	return 0;
}

C. Di-visible Confusion

这个题其实可以暴力,对于每个数的位置pos直接判断2到pos+1有没有满足条件的位置(因为随着数列的变化,一个数的位置一定是单调不增的),如果没有则输出NO。所有数都可以则输出YES。

那么为什么能暴力呢?因为如果2到pos+1所有位置都不满足条件(即a[i]都是它们的倍数),如果考虑2到pos+1所有的素数,a[i]一定是这些素数若干次幂的乘积(唯一分解定理),而1到100所有的素数的乘积就已经爆int了,所以内循环根本跑不到100,故暴力可行。

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <map>
#include <set>
#define mod 1000000007
//#define mod 998244353
#define ll long long
#define pb push_back
using namespace std;
ll fpow(ll a, ll b) {
	ll ans = 1;
	for(; b; b >>= 1) {
		if(b & 1) ans = ans * a % mod;
		a = a * a % mod;
	}
	return ans;
}
ll gcd(ll a, ll b) {
	return b ? gcd(b, a % b) : a;
}
ll n, a[100005];
int main() {
	int T = 1;
	cin >> T;
	while(T--) {
		cin >> n;
		for(int i = 1; i <= n; i++) {
			cin >> a[i];
		}
		//最后一定是一个奇数
		bool ok = 1;
		for(int i = 1; i <= n; i++) {
			bool flag = 0;
			for(int j = 2; j < i + 2; j++) {
				if(a[i] % j != 0) {
					flag = 1;
					break;
				}
			}
			if(!flag) {
				cout << "NO" << endl;
				ok = 0;
				break;
			}
		}
		if(ok) cout << "YES" << endl;
	}
	return 0;
}

D. Moderate Modular Mode

实际上是分类讨论的构造题,具体怎么构造见代码。对于最后一种情况画一下数轴就比较好理解了。

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <map>
#include <set>
#define mod 1000000007
//#define mod 998244353
#define ll long long
#define pb push_back
using namespace std;
ll fpow(ll a, ll b) {
	ll ans = 1;
	for(; b; b >>= 1) {
		if(b & 1) ans = ans * a % mod;
		a = a * a % mod;
	}
	return ans;
}
ll gcd(ll a, ll b) {
	return b ? gcd(b, a % b) : a;
}
int a[105], n;
int main() {
	int T = 1;
	cin >> T;
	while(T--) {
		ll x, y;
		cin >> x >> y;
		if(x == y) {
			cout << x << endl;
			continue;
		}
		if(x > y) {
			cout << x + y << endl;
		} else {
			if(y % x == 0) {
				cout << x << endl;
			} else {
				ll n = (x + y) / 2;
				if(n % x == y % n) {
					cout << n << endl;			
				} else {
					n = y - (y % x) / 2;
					cout << n << endl;
				}
			}
		}
	}
	return 0;
}
上一篇:勾股定理的若干证明


下一篇:C语言基础学习(7)