Atcoder AGC002 Problem Solution

Keywords: Programming

A - Range Product

If the interval contains 0, output Zero, if the number of negative numbers is odd, output Negative, otherwise output Positive.

#include<bits/stdc++.h>
using namespace std;
#define RI register int
int a,b;
int main()
{
	scanf("%d%d",&a,&b);
	if(a<=0&&b>=0) puts("Zero");
	else if(a<0&&b<0&&(b-a+1)%2) puts("Negative");
	else puts("Positive");
	return 0;
}

B - Box and Ball

Direct simulation. For the step of taking a ball from box x to box y, if there may be a red ball in box x, there may be a red ball in box y. But if you empty the x-box, there will be no red ball in the x-box.

#include<bits/stdc++.h>
using namespace std;
#define RI register int
int read() {
	int q=0;char ch=' ';
	while(ch<'0'||ch>'9') ch=getchar();
	while(ch>='0'&&ch<='9') q=q*10+ch-'0',ch=getchar();
	return q;
}
const int N=100005;
int red[N],num[N],n,m,ans;
int main()
{
	int x,y;
	n=read(),m=read();
	for(RI i=1;i<=n;++i) num[i]=1;
	red[1]=1;
	for(RI i=1;i<=m;++i) {
		x=read(),y=read();
		if(red[x]) red[y]=1;
		--num[x],++num[y];
		if(!num[x]) red[x]=0;
	}
	for(RI i=1;i<=n;++i) if(red[i]) ++ans;
	printf("%d\n",ans);
	return 0;
}

C - Knot Puzzle

Considering that there is only one knot left, the length sum of the two ropes must be greater than or equal to L, otherwise the knot cannot be solved. So find the length of the whole rope is greater than or equal to L. Untie the knot on the left from left to right, and the knot on the right from right to left, and finally untie the knot.

#include<bits/stdc++.h>
using namespace std;
#define RI register int
int read() {
	int q=0;char ch=' ';
	while(ch<'0'||ch>'9') ch=getchar();
	while(ch>='0'&&ch<='9') q=q*10+ch-'0',ch=getchar();
	return q;
}
const int N=100005;
int n,L,a[N];
void work(int x) {
	puts("Possible");
	for(RI i=1;i<x;++i) printf("%d\n",i);
	for(RI i=n-1;i>x;--i) printf("%d\n",i);
	printf("%d\n",x);
}
int main()
{
	n=read(),L=read();
	for(RI i=1;i<=n;++i) a[i]=read();
	for(RI i=1;i<n;++i)
		if(a[i]+a[i+1]>=L) {work(i);return 0;}
	puts("Impossible");
	return 0;
}

D - Stamp Rally

Integral dichotomy + rank merging and data collection.

#include<bits/stdc++.h>
using namespace std;
#define RI register int
int read() {
	int q=0;char ch=' ';
	while(ch<'0'||ch>'9') ch=getchar();
	while(ch>='0'&&ch<='9') q=q*10+ch-'0',ch=getchar();
	return q;
}
const int N=100005;
struct edge{int x,y;}e[N];
struct quesion{int x,y,z,id;}q[N],k1[N],k2[N];
int n,m,Q,top;
int ans[N],f[N],sz[N],d[N],s1[N],s2[N],tag[N];
int find(int x) {while(x!=f[x]) x=f[x];return x;}
void work(int l,int r,int ql,int qr) {
	if(ql>qr) return;
	if(l==r) {
		for(RI i=ql;i<=qr;++i) ans[q[i].id]=l;
		return;
	}
	int mid=(l+r)>>1,ktop=top,js1=0,js2=0;
	for(RI i=l;i<=mid;++i) {
		int r1=find(e[i].x),r2=find(e[i].y);
		if(r1!=r2) {
			if(d[r1]<d[r2]) swap(r1,r2);
			++top,s1[top]=r1,s2[top]=r2;
			f[r2]=r1,sz[r1]+=sz[r2];
			if(d[r1]==d[r2]) ++d[r1],tag[top]=1;
			else tag[top]=0;
		}
	}
	for(RI i=ql;i<=qr;++i) {
		int r1=find(q[i].x),r2=find(q[i].y),cango;
		if(r1==r2) cango=sz[r1];
		else cango=sz[r1]+sz[r2];
		if(cango>=q[i].z) k1[++js1]=q[i];
		else k2[++js2]=q[i];
	}
	for(RI i=1;i<=js1;++i) q[ql+i-1]=k1[i];
	for(RI i=1;i<=js2;++i) q[ql+js1-1+i]=k2[i];
	work(mid+1,r,ql+js1,qr);
	while(top>ktop) {
		f[s2[top]]=s2[top],sz[s1[top]]-=sz[s2[top]];
		if(tag[top]) --d[s1[top]];
		--top;
	}
	work(l,mid,ql,ql+js1-1);
}
int main()
{
	n=read(),m=read();
	for(RI i=1;i<=m;++i) e[i].x=read(),e[i].y=read();
	Q=read();
	for(RI i=1;i<=Q;++i)
		q[i].x=read(),q[i].y=read(),q[i].z=read(),q[i].id=i;
	for(RI i=1;i<=n;++i) f[i]=i,d[i]=sz[i]=1;
	work(1,m,1,Q);
	for(RI i=1;i<=Q;++i) printf("%d\n",ans[i]);
	return 0;
}

E - Candy Piles

Sort the candy from big to small, and then think of it as an irregular chessboard. iii lists aia_iai checkerboards. Starting from the lattice in the lower left corner, everyone's operation is to go up one grid or right one grid, and lose when there are no lattices on the upper and right sides.

According to the idea of game, there are two kinds of states: winning state N and losing state P. All the lattices without lattices above and on the right are P, and the states of other lattices (x,y) are the same as those of (x+1,y+1).

This is because the lattice state that can go to P is N, and the state that can only go to N is P. If (x+1,y+1) is P, then (x,y+1) and (x+1,y) are N, then (x,y) must be P; if (x+1,y+1) is N, then (x+1,y+2) and (x+2,y+1) have one P, then (x,y+2) and (x+2,y) have one N, then (x,y+1) and (x+1,y) have one P, and (x+1,y) have one P.

So we just need to find the largest unbounded lattice (x,x), look at its upper and right states, calculate its state, its state is (1, 1) state.

#include<bits/stdc++.h>
using namespace std;
#define RI register int
int read() {
	int q=0;char ch=' ';
	while(ch<'0'||ch>'9') ch=getchar();
	while(ch>='0'&&ch<='9') q=q*10+ch-'0',ch=getchar();
	return q;
}
const int N=100005;
int n,a[N];
int cmp(int x,int y) {return x>y;}
int main()
{
	n=read();
	for(RI i=1;i<=n;++i) a[i]=read();
	sort(a+1,a+1+n,cmp);
	for(RI i=1;i<=n;++i)
		if(i+1>a[i+1]) {
			int j=i+1;while(a[j]==i) ++j;
			int ans=(j-i-1)&1;
			ans|=(a[i]-i)&1;
			if(ans) puts("First");
			else puts("Second");
			return 0;
		}
	return 0;
}

F - Leftmost Ball

For any suffix of the sequence, the number of spheres of n+1n+1n+1 color cannot exceed the total number of colors of other colors.

We find that the first n n n colors are equivalent, so first we decide the order of adding a color, and then multiply it by an n!n!n!

f(i,j)f(i,j)f(i,j) f (i, j) denotes the number of sequential schemes of balls with I I I (except n+1n+1n+1) colors and j j j (n+1n+1n+1) colors. Consider whether to put a ball of n+1n+1n+1 color at the front of the sequence or a ball of new color, and then insert the remaining ball of new color into the back, so as to transfer.

#include<bits/stdc++.h>
using namespace std;
#define RI register int
const int mod=1000000007,N=2005,M=4000005;
int n,K,f[N][N],fac[M],ni[M];
int qm(int x) {return x>=mod?x-mod:x;}
int ksm(int x,int y) {
	int re=1;
	for(;y;y>>=1,x=1LL*x*x%mod) if(y&1) re=1LL*re*x%mod;
	return re;
}
void prework() {
	fac[0]=1;for(RI i=1;i<=n*K;++i) fac[i]=1LL*fac[i-1]*i%mod;
	ni[n*K]=ksm(fac[n*K],mod-2);
	for(RI i=n*K-1;i>=0;--i) ni[i]=1LL*ni[i+1]*(i+1)%mod;
}
int C(int d,int u) {return 1LL*fac[d]*ni[u]%mod*ni[d-u]%mod;}
int main()
{
	scanf("%d%d",&n,&K);
	if(K==1) {puts("1");return 0;}
	prework();--K;
	f[0][0]=1;
	for(RI i=1;i<=n;++i) {
		for(RI j=0;j<=i;++j) {
			if(j) f[i][j]=f[i][j-1];
			f[i][j]=qm(f[i][j]+1LL*f[i-1][j]*C(i*K+j-1,K-1)%mod);
		}
	}
	printf("%lld\n",1LL*f[n][n]*fac[n]%mod);
    return 0;
}

Posted by Chris12345 on Fri, 01 Feb 2019 23:45:17 -0800