zoukankan      html  css  js  c++  java
  • Atcoder Grand Contest 006 题解

    A - Prefix and Suffix

    模拟。

    //waz
    #include <bits/stdc++.h>
     
    using namespace std;
     
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define ALL(x) (x).begin(), (x).end()
    #define SZ(x) ((int)((x).size()))
     
    typedef pair<int, int> PII;
    typedef vector<int> VI;
    typedef long long int64;
    typedef unsigned int uint;
    typedef unsigned long long uint64;
     
    #define gi(x) ((x) = F())
    #define gii(x, y) (gi(x), gi(y))
    #define giii(x, y, z) (gii(x, y), gi(z))
     
    int F()
    {
    	char ch;
    	int x, a;
    	while (ch = getchar(), (ch < '0' || ch > '9') && ch != '-');
    	if (ch == '-') ch = getchar(), a = -1;
    	else a = 1;
    	x = ch - '0';
    	while (ch = getchar(), ch >= '0' && ch <= '9')
    		x = (x << 1) + (x << 3) + ch - '0';
    	return a * x;
    }
     
    char s[110], t[110];
     
    int N;
     
    int main()
    {
    	gi(N);
    	scanf("%s", s + 1);
    	scanf("%s", t + 1);
    	for (int i = N; i; --i)
    	{
    		int flag = 1;
    		for (int j = 1; j <= i; ++j)
    			if (s[N - i + j] != t[j])
    				flag = 0;
    		if (flag)
    		{
    			printf("%d
    ", N + N - i);
    			return 0;
    		}
    	}
    	printf("%d
    ", N + N);
    	return 0;
    }
    

      

    B - Median Pyramid Easy

    在n和n+1处构造出两个相同的肯定会一直传递到顶。

    //waz
    #include <bits/stdc++.h>
     
    using namespace std;
     
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define ALL(x) (x).begin(), (x).end()
    #define SZ(x) ((int)((x).size()))
     
    typedef pair<int, int> PII;
    typedef vector<int> VI;
    typedef long long int64;
    typedef unsigned int uint;
    typedef unsigned long long uint64;
     
    #define gi(x) ((x) = F())
    #define gii(x, y) (gi(x), gi(y))
    #define giii(x, y, z) (gii(x, y), gi(z))
     
    int F()
    {
    	char ch;
    	int x, a;
    	while (ch = getchar(), (ch < '0' || ch > '9') && ch != '-');
    	if (ch == '-') ch = getchar(), a = -1;
    	else a = 1;
    	x = ch - '0';
    	while (ch = getchar(), ch >= '0' && ch <= '9')
    		x = (x << 1) + (x << 3) + ch - '0';
    	return a * x;
    }
     
    int ans[200010], vis[200010];
     
    int main()
    {
    	int n, x;
    	gii(n, x);
    	if (n == 2)
    	{
    		if (x == 2)
    		{
    			printf("Yes
    1
    2
    3
    ");
    			return 0;
    		}
    		puts("No");
    		return 0;
    	}
    	int round = n;
    	n <<= 1;
    	--n;
    	int A = n - x, B = x - 1;
    	if (B >= 1 && A >= 2)
    	{
    		ans[round] = x;
    		ans[round + 1] = x - 1;
    		ans[round - 1] = x + 1;
    		ans[round + 2] = x + 2;
    		vis[x] = vis[x + 1] = vis[x - 1] = vis[x + 2] = 1;
    		int t = 0;
    		for (int i = 1; i <= n; ++i)
    		{
    			while (ans[t + 1]) ++t;
    			if (!vis[i]) ans[++t] = i;
    		}
    		puts("Yes");
    		for (int i = 1; i <= n; ++i)
    			printf("%d
    ", ans[i]);
    		return 0;
    	}
    	else if (B >= 2 && A >= 1)
    	{
    		ans[round] = x;
    		ans[round + 1] = x + 1;
    		ans[round - 1] = x - 1;
    		ans[round + 2] = x - 2;
    		vis[x] = vis[x + 1] = vis[x - 1] = vis[x - 2] = 1;
    		int t = 0;
    		for (int i = 1; i <= n; ++i)
    		{
    			while (ans[t + 1]) ++t;
    			if (!vis[i]) ans[++t] = i;
    		}
    		puts("Yes");
    		for (int i = 1; i <= n; ++i)
    			printf("%d
    ", ans[i]);
    		return 0;
    	}
    	puts("No");
    	return 0;
    }
    

      

    C - Rabbit Exercise

    跳一次就相当于差分数组两个位置交换一下,这是个排列的置换,可以快速幂优化。

    //waz
    #include <bits/stdc++.h>
     
    using namespace std;
     
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define ALL(x) (x).begin(), (x).end()
    #define SZ(x) ((int)((x).size()))
     
    typedef pair<int, int> PII;
    typedef vector<int> VI;
    typedef long long int64;
    typedef unsigned int uint;
    typedef unsigned long long uint64;
     
    #define gi(x) ((x) = F())
    #define gii(x, y) (gi(x), gi(y))
    #define giii(x, y, z) (gii(x, y), gi(z))
     
    int F()
    {
    	char ch;
    	int x, a;
    	while (ch = getchar(), (ch < '0' || ch > '9') && ch != '-');
    	if (ch == '-') ch = getchar(), a = -1;
    	else a = 1;
    	x = ch - '0';
    	while (ch = getchar(), ch >= '0' && ch <= '9')
    		x = (x << 1) + (x << 3) + ch - '0';
    	return a * x;
    }
     
    const int N = 100010;
     
    void mul(int *a, int *b, int n)
    {
    	static int t[N], h[N];
    	for (int i = 1; i <= n; ++i) t[i] = a[i], h[i] = b[i];
    	for (int i = 1; i <= n; ++i) a[i] = t[h[i]];
    }
     
    void fpow(int *a, int n, long long k)
    {
    	static int t[N];
    	for (int i = 1; i <= n; ++i) t[i] = i;
    	for (; k; k >>= 1)
    	{
    		if (k & 1) mul(t, a, n);
    		mul(a, a, n);
    	}
    	for (int i = 1; i <= n; ++i) a[i] = t[i];
    }
     
    int n;
     
    long long x[N];
     
    int m, a[N];
     
    long long k;
     
    int main()
    {	
    	gi(n);
    	for (int i = 1; i <= n; ++i) gi(x[i]), a[i] = i;
    	for (int i = n; i; --i) x[i] -= x[i - 1];
    	gi(m);
    	scanf("%lld", &k);
    	for (int i = 1; i <= m; ++i)
    	{
    		int p;
    		gi(p);
    		swap(a[p], a[p + 1]);
    	}
    	fpow(a, n, k);
    	for (int i = 1; i <= n; ++i)
    	{
    		//cerr << a[i] << " : " << x[a[i]] << endl;
    		x[a[i]] += x[a[i - 1]];
    		printf("%lld
    ", x[a[i]]);
    	}
    	return 0;
    }
    

      

    D - Median Pyramid Hard

    二分答案,01抵消掉,最近的连续的就是答案。

    //waz
    #include <bits/stdc++.h>
     
    using namespace std;
     
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define ALL(x) (x).begin(), (x).end()
    #define SZ(x) ((int)((x).size()))
     
    typedef pair<int, int> PII;
    typedef vector<int> VI;
    typedef long long int64;
    typedef unsigned int uint;
    typedef unsigned long long uint64;
     
    #define gi(x) ((x) = F())
    #define gii(x, y) (gi(x), gi(y))
    #define giii(x, y, z) (gii(x, y), gi(z))
     
    int F()
    {
    	char ch;
    	int x, a;
    	while (ch = getchar(), (ch < '0' || ch > '9') && ch != '-');
    	if (ch == '-') ch = getchar(), a = -1;
    	else a = 1;
    	x = ch - '0';
    	while (ch = getchar(), ch >= '0' && ch <= '9')
    		x = (x << 1) + (x << 3) + ch - '0';
    	return a * x;
    }
     
    const int N = 2e5 + 10;
     
    int n, a[N];
     
    bool check(int mid)
    {
    	for (int i = 1; i <= n - 1; ++i)
    	{
    		if ((a[n + i - 1] >= mid) == (a[n + i] >= mid)) return a[n + i] >= mid;
    		if ((a[n - i + 1] >= mid) == (a[n - i] >= mid)) return a[n - i] >= mid;
    	}
    	return a[1] >= mid;
    }
     
    int main()
    {
    	gi(n);
    	for (int i = 1; i <= 2 * n - 1; ++i) gi(a[i]);
    	int x = 1, v = 2 * n - 1;
    	for (int i = 19; ~i; --i)
    		if (x + (1 << i) <= v && check(x + (1 << i)))
    			x += 1 << i;
    	printf("%d
    ", x);
    }
    

      

    E - Rotate 3x3

    首先一列本质就是一个数字带有正反。

    算一下移动次数和翻转次数的奇偶性判断一下即可。

    //waz
    #include <bits/stdc++.h>
     
    using namespace std;
     
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define ALL(x) (x).begin(), (x).end()
    #define SZ(x) ((int)((x).size()))
     
    typedef pair<int, int> PII;
    typedef vector<int> VI;
    typedef long long int64;
    typedef unsigned int uint;
    typedef unsigned long long uint64;
     
    #define gi(x) ((x) = F())
    #define gii(x, y) (gi(x), gi(y))
    #define giii(x, y, z) (gii(x, y), gi(z))
     
    int F()
    {
    	char ch;
    	int x, a;
    	while (ch = getchar(), (ch < '0' || ch > '9') && ch != '-');
    	if (ch == '-') ch = getchar(), a = -1;
    	else a = 1;
    	x = ch - '0';
    	while (ch = getchar(), ch >= '0' && ch <= '9')
    		x = (x << 1) + (x << 3) + ch - '0';
    	return a * x;
    }
     
    const int N = 1e5 + 10;;
     
    int a[3][N], n, s[N], d[N], p[N], cnt[2], ds[2];
     
    int tree[N];
     
    void change(int x) { for (; x; x -= x & -x) ++tree[x]; }
     
    int query(int x) { int v = 0; for (; x <= n; x += x & -x) v += tree[x]; return v; }
     
    int main()
    {
    	gi(n);
    	for (int j = 0; j < 3; ++j)
    		for (int i = 1; i <= n; ++i)
    			gi(a[j][i]);
    	for (int i = 1; i <= n; ++i)
    	{
    		if (a[0][i] == a[1][i] + 1 && a[1][i] == a[2][i] + 1) s[i] = a[0][i] / 3, d[i] = 1;
    		else if (a[0][i] == a[1][i] - 1 && a[1][i] == a[2][i] - 1) s[i] = a[2][i] / 3, d[i] = 0;
    		else return puts("No"), 0;
    		if ((s[i] & 1) != (i & 1)) return puts("No"), 0;
    		cnt[i & 1] += d[i];
    	}
    	for (int i = 1; i <= n; ++i) p[s[i]] = i;
    	for (int i = 1; i <= n; i += 2) 
    	{
    		int now = p[i] + (query(p[i]) << 1);
    		ds[1] += (abs(now - i) >> 1) & 1;
    		change(p[i]);
    	}
    	memset(tree, 0, sizeof tree);
    	for (int i = 2; i <= n; i += 2)
    	{
    		int now = p[i] + (query(p[i]) << 1);
    		ds[0] += (abs(now - i) >> 1) & 1;
    		change(p[i]);
    	}
    	if ((cnt[0] & 1) != (ds[1] & 1) || (cnt[1] & 1) != (ds[0] & 1)) return puts("No"), 0;
    	puts("Yes");
    	return 0;
    }
    

      

    F - Blackout

    本质是一个有向图问题,我们将图染成三种颜色做一下就好了。

    //waz
    #include <bits/stdc++.h>
     
    using namespace std;
     
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define ALL(x) (x).begin(), (x).end()
    #define SZ(x) ((int)((x).size()))
     
    typedef pair<int, int> PII;
    typedef vector<int> VI;
    typedef long long int64;
    typedef unsigned int uint;
    typedef unsigned long long uint64;
     
    #define gi(x) ((x) = F())
    #define gii(x, y) (gi(x), gi(y))
    #define giii(x, y, z) (gii(x, y), gi(z))
     
    int F()
    {
    	char ch;
    	int x, a;
    	while (ch = getchar(), (ch < '0' || ch > '9') && ch != '-');
    	if (ch == '-') ch = getchar(), a = -1;
    	else a = 1;
    	x = ch - '0';
    	while (ch = getchar(), ch >= '0' && ch <= '9')
    		x = (x << 1) + (x << 3) + ch - '0';
    	return a * x;
    }
     
    const int N = 1e5 + 10;
     
    int n, m;
     
    vector<int> e1[N], e2[N]; 
     
    bool vis[N];
     
    int co[N], flag, cnt[3], s, e;
     
    void dfs(int u)
    {
    	vis[u] = 1;
    	++s;
    	++cnt[co[u]];
    	for (auto v : e1[u])
    	{
    		++e;
    		if (vis[v])
    		{
    			if (co[v] != (co[u] + 1) % 3)
    				flag = 0;
    			continue;
    		}
    		co[v] = (co[u] + 1) % 3;
    		dfs(v);		
    	}
    	for (auto v : e2[u])
    	{
    		if (vis[v])
    		{
    			if (co[v] != (co[u] + 2) % 3)
    				flag = 0;
    			continue;
    		}
    		co[v] = (co[u] + 2) % 3;
    		dfs(v);
    	}
    }
     
    long long ans;
     
    int main()
    {
    	gii(n, m);
    	for (int i = 1; i <= m; ++i)
    	{
    		int u, v;
    		gii(u, v);
    		e1[u].pb(v);
    		e2[v].pb(u);
    	}
    	for (int i = 1; i <= n; ++i)
    	{
    		if (!vis[i])
    		{
    			e = 0;
    			s = 0;
    			flag = 1;
    			cnt[0] = cnt[1] = cnt[2] = 0;
    			dfs(i);
    			if (!flag)
    			{
    				ans += 1LL * s * s;
    			}
    			else if (cnt[0] && cnt[1] && cnt[2])
    			{
    				ans += 1LL * cnt[0] * cnt[1] + 1LL * cnt[1] * cnt[2] + 1LL * cnt[0] * cnt[2];
    			}
    			else ans += e;
    		}
    	}
    	printf("%lld
    ", ans);
    	return 0;
    }
    

      

  • 相关阅读:
    交叉编译fw_printenv
    解压 xxxx.cpio.gz.u-boot
    创建Uboot 环境变量 bin 文件
    Linux快速显示图片
    移动终端的GPU显卡介绍
    Video Mode Timings
    change systemd service
    device tree DTB DTC 相互转换
    如何写出安全的API接口(参数加密+超时处理+私钥验证+Https)- 续(附demo)
    解决h5在ios 微信中 input框键盘收起 页面底部留白
  • 原文地址:https://www.cnblogs.com/AnzheWang/p/9624230.html
Copyright © 2011-2022 走看看