Codeforces Round #818 (Div. 2) A-E

38 篇文章 0 订阅
37 篇文章 0 订阅

题目链接:Dashboard - Codeforces Round #818 (Div. 2) - Codeforces

A - Madoka and Strange Thoughts

#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1
typedef long long ll;
typedef unsigned long long ull;
const int mx = 5e3 + 10;
const int mod = 998244353;
typedef pair <int, int> pa;
 
 
int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		int n;
		scanf("%d", &n);
		ll ans = 0;
		ans += n;
		ans += n / 2 * 2;
		ans += n / 3 * 2;
		printf("%lld\n", ans);
	}
	
    return 0;
}

B - Madoka and Underground Competitions

#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1
typedef long long ll;
typedef unsigned long long ull;
const int mx = 5e3 + 10;
const int mod = 998244353;
typedef pair <int, int> pa;

char str[mx][mx];

int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		int n,k,r,c;
		scanf("%d%d%d%d", &n, &k, &r, &c);
		int ii = (r - 1) % k + 1;
		int jj = (c - 1) % k + 1;
		vector <pa> vec;
		vec.push_back(pa(ii, jj));
		
		for (int i=1;i<=n;i++) {
			for (int j=1;j<=n;j++) {
				str[i][j] = '.';
			}
			str[i][n+1] = 0;
		}
		for (int i=r, j = c;;i++,j++) {
			int u = i % k + 1;
			int v = j % k + 1;
			if (u == ii) break;
			vec.push_back(pa(u, v));
		}
		for (pa temp: vec) {
			int u = temp.first;
			int v = temp.second;
			
			for (int j=v; j<=n; j+=k)
				for (int i=u; i<=n; i+=k) {
					str[i][j] = 'X';
				}
			
			for (int j=u; j<=n; j+=k) {
				for (int i=v; i<=n; i+=k) {
					str[j][i] = 'X';
				}
			}
		}
		for (int i=1;i<=n;i++) {
			printf("%s\n", str[i] + 1);
		}
	}
	
	
    return 0;
}

C - Madoka and Formal Statement

解题思路:贪心。如果b[i] - b[i+1] > 1,那么就说明b[i]不能再增长了,这个时候如果a[i] != b[i],那么肯定是不行的,反之是可以的。

#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1
typedef long long ll;
typedef unsigned long long ull;
const int mx = 2e5 + 10;
const int mod = 998244353;
typedef pair <int, int> pa;

int a[mx], b[mx];

int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		int n;
		scanf("%d", &n);
		for (int i=1;i<=n;i++)
			scanf("%d", a + i);
		for (int i=1;i<=n;i++)
			scanf("%d", b + i);
		int flag = 1;
		for (int i=1;i<=n;i++) {
			if (a[i] > b[i]) {
				flag = 0;
				break;
			}
			if (i == n) {
				if (b[i] - b[1] > 1 && a[i] != b[i])
					flag = 0;
			} else {
				if (b[i] - b[i+1] > 1 && a[i] != b[i])
					flag = 0;
			}
		}
		puts(flag? "YES":"NO");
	}
	
	
    return 0;
}

D - Madoka and The Corruption Scheme

解题思路:可以找规律,也可以推出来答案是\sum_{i = 0}^{k}C_{n}^{i}。可知当i == k时,刚好为2^{n}

#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define lson l,mid,rt<<1
#define rson mid+1,r,(rt<<1)|1
typedef long long ll;
const int mx = 3e5 + 10;
const int mod = 1e9 + 7;

ll f[mx];

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


int main() {
	f[0] = 1;
	for (int i=1;i<mx;i++) {
		f[i] = i * f[i-1] % mod;
	}
	int n, k;
	scanf("%d%d", &n, &k);
	if (k >= n) {
		printf("%lld\n", qpow(2, n));
		return 0;
	}
	ll ans = 0;
	for (int i=0; i<= k; i++) {
		ll temp = qpow(f[n-i], mod-2) * qpow(f[i], mod-2) % mod;
		ans += f[n] * temp % mod;
		ans %= mod;
	}
	printf("%lld\n", ans);
	return 0;
}

E - Madoka and The Best University

解题思路:求lcm(c, gcd(a,b)),我们假设a + b = j,那么c = n - j。去枚举gcd(a,b)的,令a = x,那么b= j - x, 如果gcd(x, j - x) = i,那么gcd(x/i, j/i) = 1,所以就是求和j互质的x有多少个,因为要除以i,根据欧拉函数可知,与j/i互质的有phi[j/i]个。最终答案就是 (n - j) * i / gcd(i, n - j) *phi[j/i]。时间复杂度为O( n * log(n) * log(n))

#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define lson l,mid,rt<<1
#define rson mid+1,r,(rt<<1)|1
typedef long long ll;
const int mx = 1e5 + 10;
const int mod = 1e9 + 7;

int phi[mx];
vector <int> pi;
bool vis[mx];

void init() {
	phi[1] = 1;
	for (int i=2;i<mx;i++) {
		if (!vis[i]) {
			pi.push_back(i);
			phi[i] = i - 1;
		} 
		for (int v: pi) {
			if (i * v >= mx)
				break;
			vis[i * v] = 1;
			if (i % v == 0) {
				phi[i * v] = phi[i] * v;
				break;
			}
			phi[i * v] = phi[i] * phi[v];
		}
	}
}

int main() {
	init();
	int n;
	scanf("%d", &n);
	ll ans = 0;
	for (int i=1;i<=n;i++) {
		for (int j=2*i; j<n;j+=i) {
			ans += 1ll * (n-j) * i / __gcd(i, n-j) * phi[j/i];
			ans %= mod;
		}
	}
	printf("%lld\n", ans);
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值