Codeforces Round #747 (Div. 2) (A - E1)

A. Consecutive Sum Riddle

水题 找两个数l, r 使得l, r之间所有数之和为n 找 -(n - 1) 到 n就好

代码

#include 

using namespace std;

typedef long long ll;

ll n, l, r;

void solve()
{
	cin >> n;
	cout << 1 - n << ' ' << n << endl;
}

int main()
{
	int t;
	cin >> t;
	
	while(t -- )
	{
		solve();
	}
	
	return 0;
} 

B. Special Numbers

我们可以把k转化为二进制 有点类似于快速幂的解法 水题

代码

#include 

using namespace std;

typedef long long ll;

const ll P = 1e9 + 7;

ll read()
{
	ll x = 0, k = 1;
	char c = getchar();
	while (c < '0' || c > '9')
	{
		if (c == '-') k = -1;
		c = getchar();
	}
	while (c >= '0' && c <= '9')
	{
		x = (x << 3) + (x << 1) + (c ^ 48);
		c = getchar();
	}
	return x * k;
}

ll n, k;

void solve()
{
	n = read(), k = read();
	ll ans = 0, t = 1;;
	
	while (k)
	{
		if (k & 1) (ans += t) %= P;
		(t *= n) %= P;
		k >>= 1;
	}
	
	cout << ans << endl;
}

int main()
{
	int t;
	cin >> t;
	
	while (t -- )
	{
		solve();
	}
	
	return 0;
}

C. Make Them Equal

水题 如果第n位相同 就取一个pos为n即可 如果n位不同 则从n/2到n取第一个相同的位数(n/2到n不存在n的因子 更不存在比n小的数的因子) 如果全都不同 则取n-1 和n即可

代码

#include 

using namespace std;

const int N = 3e5 + 10;

int read()
{
	int x = 0, k = 1;
	char c = getchar();
	while (c < '0' || c > '9')
	{
		if (c == '-') k = -1;
		c = getchar();
	}
	while (c >= '0' && c <= '9')
	{
		x = (x << 3) + (x << 1) + (c ^ 48);
		c = getchar();
	}
	return x * k;
}

int n;
char c;
char st[N];

void solve()
{
	n = read();
	cin >> c >> st + 1;
	int pos = -1;
	
	for (int i = 1; i <= n; i ++ ) 
		if (st[i] != c) pos = i;
	
	if (pos == -1) puts("0");
	else if (pos != n) printf("1\n%d\n", n);
	else
	{
		for (int i = n; i > n / 2; i -- )
			if (st[i] == c) 
			{
				pos = i;
				break;
			}
		if (pos == n)
			printf("2\n%d %d\n", n - 1, n);
		else printf("1\n%d\n", pos);
	}
}

int main()
{
	int t;
	cin >> t;
	
	while (t -- )
	{
		solve();
	}
	
	return 0;
}

D. The Number of Imposters

在很火的amongus游戏中会有m个人发表一次意见 说某人是否是卧底 问可能的最大的卧底数量为多少
我们可以这样考虑 假如a说b是好人 那么a和b肯定都是好人或者都是卧底 即身份相同 如果a说b是卧底 那么a和b身份肯定是相反的 所以我们可以想到用权值并查集来做这个题 用0和1来分别表示身份相同和身份不同 最后取每个集合中某个身份的最大值 相加即为答案
很经典的一种并查集题

代码

#include 

#define rep(i, n) for (int i = 1; i <= (n); i ++ )

using namespace std;

const int N = 2e5 + 10;

inline int read()
{
	register int x = 0, k = 1;
	char c = getchar();
	while (c < '0' || c > '9') 
	{
		if (c == '-') k = -1;
		c = getchar();
	}
	while (c >= '0' && c <= '9')
	{
		x = (x << 3) + (x << 1) + (c ^ 48);
		c = getchar();
	}
	return x * k;
}

int n, m;
int p[N], dis[N], cou[N][2];

int find(int x)
{
	if (x != p[x])
	{
		int root = find(p[x]);
		dis[x] ^= dis[p[x]];
		p[x] = root;
	}
	return p[x];
}

void solve()
{
	n = read(), m = read();
	rep(i, n) p[i] = i, dis[i] = 0, cou[i][0] = 1, cou[i][1] = 0;
	
	bool flag = 1;
	rep(i, m){
		int a, b; char c[10];
		a = read(), b = read(); scanf("%s", c);
		bool val = c[0] == 'i';
		int pa = find(a), pb = find(b);		
		
		if (pa == pb){
			if ((dis[a] ^ dis[b]) != val) flag = false;
		}
		else{
			p[pb] = pa;
			dis[pb] = dis[a] ^ dis[b] ^ val;
			cou[pa][1] += cou[pb][dis[pb] ^ 1];
			cou[pa][0] += cou[pb][dis[pb]];
		}
	}
	
	if (!flag) {puts("-1"); return;}
	
	int res = 0;
	rep(i, n) if (i == find(i)) res += max(cou[i][1], cou[i][0]);
	printf("%d\n", res);
}

int main()
{
	int t;
	t = read();
	
	while (t -- )
	{
		solve();
	}
	
	return 0;
}

E1. Rubik’s Cube Coloring (easy version)

给定一棵树 每个结点都可以染色 但是相邻结点有限制 即有两种颜色不能染
则每个结点有4中方式 根节点有6种 最后求相乘值即可
代码

#include 

using namespace std;

typedef long long ll;

const int N = 3e5 + 10;
const ll P = 1e9 + 7;

int read()
{
	int x = 0, k = 1;
	char c = getchar();
	while (c < '0' || c > '9')
	{
		if (c == '-') k = -1;
		c = getchar();
	}
	while (c >= '0' && c <= '9')
	{
		x = (x << 3) + (x << 1) + (c ^ 48);
		c = getchar();
	}
	return x * k;
}

ll k;

ll qmi(ll a, ll k)
{
	ll res = 1;
	while (k)
	{
		if (k % 2 == 1) res = res * a % P;
		k >>= 1;
		a = a * a % P;
	}
	return res;
}

void solve()
{
	cin >> k;
	ll k1 = (1ll << k) - 2;
	ll ans = 6 * qmi(4ll, k1) % P;
	cout << ans << endl;
}

int main()
{

		solve();

	
	return 0;
}

你可能感兴趣的:(Codeforces,算法)