AtCoder Grand Contest 008 题解

A - Simple Calculator

模拟+分类讨论即可。

//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 work(int x, int y)
{
	if (x <= y) return y - x;
	else return x - y + 2;
}

int main()
{
	int x, y;
	gii(x, y);
	printf("%d\n", min(work(x, y), min(1 + work(-x, y), min(1 + work(x, -y), 2 + work(-x, -y)))));
}

  

B - Contiguous Repainting

我们发现可以找到一段连续的k个,其它部分可以任意挑,连续的那一段要么全选要么全不选,枚举连续段在哪即可。

//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 a[100010];

int64 s1[100010], s2[100010], ans;

int main()
{
	int n, k;
	gii(n, k);
	for (int i = 1; i <= n; ++i) gi(a[i]), s1[i] = s1[i - 1] + a[i], s2[i] = s2[i - 1] + (a[i] > 0 ? a[i] : 0);
	for (int i = 1; i <= n - k + 1; ++i)
	{
		int j = i + k - 1;
		long long s = s2[i - 1] + s2[n] - s2[j];
		s += max(s1[j] - s1[i - 1], 0LL);
		ans = max(ans, s);
	}
	printf("%lld\n", ans);
	return 0;
}

  

C - Tetromino Tiling

我们发现只有1,2,4,5这四种才有可能组合出完整矩形,其中两个相同的可以组成4*2的,或者1 4 5各一个组成一个6*2的,两种情况取max就好。

//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 a[7], b[7];

int64 ans = 0, res = 0;

int main()
{
	for (int i = 0; i < 7; ++i) gi(a[i]), b[i] = a[i];
	ans += 4LL * (a[0] >> 1); a[0] &= 1;
	ans += 4LL * (a[3] >> 1); a[3] &= 1;
	ans += 4LL * (a[4] >> 1); a[4] &= 1;
	ans += 2LL * a[1]; a[1] = 0;
	if (a[0] && a[3] && a[4]) ans += 6;
	if (b[0] && b[3] && b[4]) --b[0], --b[3], --b[4], res += 6;
	res += 4LL * (b[0] >> 1);
	res += 4LL * (b[3] >> 1);
	res += 4LL * (b[4] >> 1);
	res += 2LL * b[1];
	printf("%lld\n", max(ans, res) >> 1);
}

  

D - K-th K

按坐标排序后贪心放就好了。

//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;
}

PII x[510];

int a[510 * 510];

int n;

int main()
{
	gi(n);
	for (int i = 1; i <= n; ++i) gi(x[i].fi), x[i].se = i;
	int k = 1;
	sort(x + 1, x + n + 1);
	for (int i = 1; i <= n; ++i)
	{
		a[x[i].fi] = x[i].se;
		for (int j = 1; j < x[i].se; ++j)
		{
			while (a[k]) ++k;
			a[k] = x[i].se;
		}
		if (k > x[i].fi)
		{
			puts("No");
			return 0;
		}
	}
	k = 1;
	for (int i = 1; i <= n; ++i)
	{
		for (int j = x[i].se + 1; j <= n; ++j)
		{
			while (a[k]) ++k;
			if (k < x[i].fi)
			{
				puts("No");
				return 0;
			}
			a[k] = x[i].se;
		}
	}
	puts("Yes");
	for (int i = 1; i <= n * n; ++i)
		printf("%d ", a[i]);
}

  

E - Next or Nextnext

不会做……先咕着。

F - Black Radius

计算出每个点和它父亲的d值最大多少是不同的,最后DP一下就好了。

//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;

VI edge[N];

char str[N];

int n, in[N], out[N], dfs_clock, fa[N], dep[N], d[N];

void dfs1(int u)
{
	in[u] = ++dfs_clock;
	for (auto v : edge[u])
	{
		if (v == fa[u]) continue;
		fa[v] = u;
		dep[v] = dep[u] + 1;
		dfs1(v);
	}
	out[u] = dfs_clock;
}

struct node
{
	int l, r;
	int val, tag;
	void add(int x) { val += x; tag += x; }
} t[N << 2];

void push_up(int o) { t[o].val = max(t[o << 1].val, t[o << 1 | 1].val); }

void push_down(int o)
{
	if (t[o].tag)
	{
		t[o << 1].add(t[o].tag);
		t[o << 1 | 1].add(t[o].tag);
		t[o].tag = 0;
	}
}

void build(int o, int l, int r)
{
	t[o].l = l, t[o].r = r;
	if (l == r)
	{
		t[o].val = d[l];
		return;
	}
	int mid = (l + r) >> 1;
	build(o << 1, l, mid);
	build(o << 1 | 1, mid + 1, r);
	push_up(o);
}

int query(int o, int l, int r)
{
	if (t[o].r < l || r < t[o].l) return 0;
	if (l <= t[o].l && t[o].r <= r) return t[o].val;
	push_down(o);
	return max(query(o << 1, l, r), query(o << 1 | 1, l, r));
}

void add(int o, int l, int r, int x)
{
	if (t[o].r < l || r < t[o].l) return;
	if (l <= t[o].l && t[o].r <= r) return t[o].add(x);
	push_down(o);
	add(o << 1, l, r, x);
	add(o << 1 | 1, l, r, x);
	push_up(o);
}

/*
int pa[N];

int find(int x) { return x == pa[x] ? x : pa[x] = find(pa[x]); }

void unit(int x, int y)
{
	x = find(x), y = find(y);
	if (x == y) return;
	pa[x] = y; str[y] |= str[x];
}
*/

int mxt[N], mxa[N], mxb[N];

void dfs2(int u)
{
	int a = query(1, in[u], out[u]) + 1;
	int b = max(query(1, 1, in[u] - 1), query(1, out[u] + 1, n));
	if (fa[u]) mxt[u] = min(a + 1, b), mxa[u] = a + 1, mxb[u] = b; else mxt[u] = a; // >= t[u] : GG
	for (auto v : edge[u])
	{
		if (v == fa[u]) continue;
		add(1, in[v], out[v], -1);
		add(1, 1, in[v] - 1, 1);
		add(1, out[v] + 1, n, 1);
		dfs2(v);
		add(1, in[v], out[v], 1);
		add(1, 1, in[v] - 1, -1);
		add(1, out[v] + 1, n, -1);
	}
}

int64 ans;

int num[N];

void dfs3(int u)
{
	//cerr << u << ", " << mxt[u] << " : " << mxa[u] << ", " << mxb[u] << endl;
	for (auto v : edge[u])
	{
		if (v == fa[u]) continue;
		dfs3(v);
		if (mxt[v] > num[v]) ans += mxt[v] - num[v], num[u] = min(num[u], min(mxa[v] - 1, mxb[v] + 1));
		else num[u] = min(num[u], num[v]);
	}
}

int main()
{
	gi(n);
	for (int i = 1; i < n; ++i)
	{
		int u, v;
		gii(u, v);
		edge[u].pb(v);
		edge[v].pb(u);
	}
	scanf("%s", str + 1);
	for (int i = 1; i <= n; ++i) str[i] -= ‘0‘;
	for (int i = 1; i <= n; ++i) if (!str[i]) num[i] = N;
	int root = 1;
	for (; !str[root]; ++root);
	dfs1(root);
	for (int i = 1; i <= n; ++i) d[in[i]] = dep[i];
	build(1, 1, n);
	dfs2(root);
	dfs3(root);
	printf("%lld\n", ans + mxt[root]);
	return 0;
}

  

原文地址:https://www.cnblogs.com/AnzheWang/p/9633097.html

时间: 2024-08-29 10:15:36

AtCoder Grand Contest 008 题解的相关文章

AtCoder Grand Contest 008题解

传送门 \(A\) 分类讨论就行了 然而我竟然有一种讨论不动的感觉 int x,y; inline int min(R int x,R int y){return x<y?x:y;} inline int min(R int a,R int b,R int c,R int d){ return min(min(a,b),min(c,d)); } inline int calc(R int x,R int y){return y>=x?y-x:x-y+2;} int main(){ scanf(

AtCoder Grand Contest 007题解

传送门 \(A\) 咕咕咕 //quming #include<bits/stdc++.h> #define R register #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i) #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i) #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v) template<

AtCoder Grand Contest 014题解

传送门 \(A\) 首先大力猜测一下答案不会很大,所以次数大于\(10^6\)输出\(-1\)就行了 不过我并不会证上界,据说是因为如果\(a=b=c\)且都是偶数肯定\(-1\),否则设\(a\leq b\leq c\),则最大最小值的差为\(c-a\),一次操作之后变成了\({c-a\over 2}\),所以操作次数就是\(\log\)级别的了 typedef long long ll; ll a,b,c,sum;int res; int main(){ scanf("%lld%lld%ll

AtCoder Grand Contest 039 题解

传送门 \(A\) 首先只有一串的情况下,遇到相同的肯定是改后面那一个最优,然后两串的话可能要分奇偶讨论一下 //quming #include<bits/stdc++.h> #define R register #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i) #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i) #define go(u) for(int i=head[u],v=

Atcoder Grand Contest 003 题解

A - Wanna go back home 如果有S就必须要有N,反之亦然,如果有E必须要有W,反之亦然.判断一下就好了. //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

AtCoder Grand Contest 013 题解

A - Sorted Arrays 贪心,看看不下降和不上升最长能到哪,直接转移过去即可. 1 //waz 2 #include <bits/stdc++.h> 3 4 using namespace std; 5 6 #define mp make_pair 7 #define pb push_back 8 #define fi first 9 #define se second 10 #define ALL(x) (x).begin(), (x).end() 11 #define SZ(x

AtCoder Grand Contest 015 题解

A - A+...+B Problem 可以取到的值一定是一段区间.所以答案即为max-min+1 1 //waz 2 #include <bits/stdc++.h> 3 4 using namespace std; 5 6 #define mp make_pair 7 #define pb push_back 8 #define fi first 9 #define se second 10 #define ALL(x) (x).begin(), (x).end() 11 #define

AtCoder Grand Contest 006 题解

传送门 \(A\) 咕咕 const int N=105; char s[N],t[N];int n; inline bool eq(R int k){fp(i,1,k)if(s[n-k+i]!=t[i])return false;return true;} int main(){ scanf("%d%s%s",&n,s+1,t+1); fd(k,n,0)if(eq(k))return printf("%d\n",(n<<1)-k),0; ret

AtCoder Grand Contest 013题解

传送门 \(A\) 先把相同的缩一起,然后贪心就可以了 //quming #include<bits/stdc++.h> #define R register #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i) #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i) #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v