Codeforces Round #736 (Div. 2) 题解

比赛地址:https://codeforces.com/contest/1549

只有 ABCDE 的题解,F1F2 不会。

A

由于 \(P\) 是奇数,所以只需让 \(a=2,b=\frac{P-1}2\) 即可。

typedef long long ll;

void mian(){
	int P;scanf("%d",&P);
	P--;
	if(P==4)printf("%d %d\n",2,4);
	else printf("%d %d\n",2,P/2);
}

B

能放就放即可。

typedef long long ll;

const int N=2e5;

int n,a[N+10],b[N+10],vis[N+10];

void mian(){
	for(int i=1;i<=n;i++)a[i]=b[i]=vis[i]=0;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%1d",&a[i]);
	for(int i=1;i<=n;i++)scanf("%1d",&b[i]);
	int ans=0;
	for(int i=1;i<=n;i++){
		if(b[i]==1){
			if(a[i-1]==1&&!vis[i-1]){vis[i-1]=1;ans++;}
			else if(a[i]==0&&!vis[i]){vis[i]=1;ans++;}
			else if(a[i+1]==1&&!vis[i+1]){vis[i+1]=1;ans++;}
		}
	}
	printf("%d\n",ans);
}

C

把这些关系想成是一个有向图,边都是从编号小的点连到编号大的点。

那么,如果一个点有出度,这个点就要 GG。

维护一下每个点的出度即可。

typedef long long ll;

const int N=2e5;

int n,m,q,ans,outd[N+10];

void mian(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		int u,v;scanf("%d%d",&u,&v);
		if(u>v)std::swap(u,v);
		outd[u]++;
	}
	ans=n;
	for(int i=1;i<=n;i++)
		if(outd[i]>=1)ans--;
	scanf("%d",&q);
	while(q--){
		int opt,u,v;scanf("%d",&opt);
		if(opt==1){
			scanf("%d%d",&u,&v);
			if(u>v)std::swap(u,v);
			outd[u]++;
			if(outd[u]==1)ans--;
		}
		if(opt==2){
			scanf("%d%d",&u,&v);
			if(u>v)std::swap(u,v);
			outd[u]--;
			if(outd[u]==0)ans++;
		}
		if(opt==3)printf("%d\n",ans);
	}
}

D

如果一个数组是合法的,那么这个数组的差分数组的 \(\gcd\)\(\gt 1\)

先求出 \(a\) 的差分数组 \(d\)。对于每个 \(l\in[1,n-1]\),我们要找到最大的 \(r\),使得 \(\gcd_{i=l}^rd_i\gt 1\)

倍增实现即可。

typedef long long ll;

const int N=2e5;
const int LOGN=20;

int n;
ll a[N+10],d[N+10],f[N+10][LOGN+5];

ll gcd(ll a,ll b){return !b?a:gcd(b,a%b);}

void mian(){
	for(int i=1;i<=n+1;i++){
		a[i]=d[i]=0;
		for(int j=0;j<=LOGN;j++)
			f[i][j]=0;
	}
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%lld",a+i);
	for(int i=1;i<=n;i++)
		d[i]=std::abs(a[i+1]-a[i]),f[i][0]=d[i];
	for(int j=1;j<=LOGN;j++)
		for(int i=1;i+(1<<(j-1))<=n;i++)
			f[i][j]=gcd(f[i][j-1],f[i+(1<<(j-1))][j-1]);
	int ans=1;
	for(int i=1;i<=n;i++){
		ll now=d[i];
		int r=i;
		if(now<=1)continue;
		for(int j=LOGN;~j;j--)
			if(r+(1<<j)<=n&&f[r][j]>1&&gcd(now,f[r][j])>1)now=gcd(now,f[r][j]),r+=(1<<j);
		ans=std::max(ans,r-i+1);
	}
	printf("%d\n",ans);
}

E

题目相当于让我们求:

\[\sum_{i=0}^n\binom{3i}x \]

考虑用 dp 求出这个式子。设:

\[f_{x,j}=\sum_{i=0}^n\binom{3i+j}x,0\le j\le 2 \]

那么答案就是 \(f_{x,0}\)

我们运用公式 \(\binom nm=\binom{n-1}m+\binom{n-1}{m-1}\),可以推出 \(f_{x,1},f_{x,2}\) 的转移方程:

\[f_{x,j}=\sum_{i=0}^n\binom{3i+j}x=\sum_{i=0}^n\binom{3i+j-1}x+\sum_{i=0}^n\binom{3i+j-1}{x-1}=f_{x,j-1}+f_{x-1,j-1},1\le j\le 2 \]

我们运用公式 \(\sum_{i=0}^n\binom ix=\binom{n+1}{x+1}\),可以推出 \(f_{x,0}\) 的转移方程:

\[f_{x,0}=(f_{x,0}+f_{x,1}+f_{x,2})-f_{x,1}-f_{x,2}=\sum_{i=0}^{3n+2}\binom ix-f_{x,1}-f_{x,2}=\binom{3n+3}{x+1}-f_{x,1}-f_{x,2} \]

于是,我们得到了一个方程组:

\[\begin{cases} f_{x,0}=\binom{3n+3}{x+1}-f_{x,1}-f_{x,2}\\ f_{x,1}=f_{x,0}+f_{x-1,0}\\ f_{x,2}=f_{x,1}+f_{x-1,1} \end{cases} \]

解得:

\[\begin{cases} f_{x,0}=\dfrac{\binom{3n+3}{x+1}-2f_{x-1,0}-f_{x-1,1}}{3}\\ f_{x,1}=f_{x,0}+f_{x-1,0}\\ f_{x,2}=f_{x,1}+f_{x-1,1} \end{cases} \]

边界:\(f_{0,0}=f_{0,1}=f_{0,2}=n+1\)

typedef long long ll;

const int N=1e6;
const int P=1e9+7;

int n,m,f[N*3+10][3];
int fac[N*3+10],ifac[N*3+10];

inline int qpow(int a,int b,int p){
	int res=1;
	while(b){if(b&1)res=1LL*res*a%p;a=1LL*a*a%p;b>>=1;}
	return res;
}

inline int inv(int a,int p){return qpow(a,p-2,p);}

void initComb(int p){
	int lim=std::min(n*3+5,p-1);
	fac[0]=1;for(int i=1;i<=lim;i++)fac[i]=1LL*fac[i-1]*i%p;
	ifac[lim]=inv(fac[lim],p);for(int i=lim-1;i>=0;i--)ifac[i]=1LL*ifac[i+1]*(i+1)%p;
}

inline int C(int a,int b,int p){if(a<b)return 0;else return 1LL*fac[a]*ifac[b]%p*ifac[a-b]%p;}

void mian(){
	scanf("%d%d",&n,&m);
	initComb(P);
	f[0][0]=f[0][1]=f[0][2]=n+1;
	int inv3=inv(3,P);
	for(int i=1;i<=n*3;i++){
		f[i][0]=1LL*(((C(3*n+3,i+1,P)-2*f[i-1][0]%P-f[i-1][1])%P+P)%P)*inv3%P;
		f[i][1]=(f[i][0]+f[i-1][0])%P;
		f[i][2]=(f[i][1]+f[i-1][1])%P;
	}
	while(m--){
		int x;scanf("%d",&x);
		printf("%d\n",f[x][0]);
	}
}
posted @ 2021-08-02 11:07  registerGen  阅读(24)  评论(0编辑  收藏  举报