Codeforces Round 934 (Div. 1)

LINK

CF1943A

签到题

CF1943B

注意到对于k-bad的限制其实十分严格,考虑一个长为len的区间是k-bad的情况

\(len=k\),直接用manachar判断
\(k=2k'\),仿照border推循环节的操作,该区间形如\(abab\),可以记录每个字符的\(lastpos\),计算区间中\(pos-lastpos\)为2的位置个数
\(k=2k'+1\),循环节会在中间相交,该区间为\(aaa\)

mark

最开始想的方向是离线询问区间然后考虑左右端点的移动,有类似的pam做法

CF1943C

注意到一次染色最多只能对一条链上的两个点产生影响。考虑树的直径。

\(len=2k+1\),则至少要\(k+1\)次操作
\(len=4k\),则对直径间隔黑白染色,黑点关于一个白点对称,白点同理,可以取到\(2k\)
\(len=4k+2\),一次操作最多会对同色两个点产生影响,但同色点为奇数所以无法取到\(2k\)

mark

第三步的证明卡住了...脑残一样的...
想在直径上dp,但搞不出状态...通过染色的方法来证明确实不错...

CF1943D1

注意到一种情况合法当且仅当不存在 \(i\)\(a_i>a_{i+1}+a_{i-1}\)
若不存在,则一定可通过一次操作到另一种合法情况
dp随便前缀和优化一下就行了,可以滚

mark

有点神仙,400的范围很容易往区间dp想
更好的证明是操作相当于把差分数组\(i<j\)\(d[i]+=1,d[j]-=1\),相当于是把正数与负数配对,考虑前缀和

CF1943D2

无法有相邻两个位置不合法,第i个位置不合法的方案数由i-1合法的方案数和i-1,i+1的值决定。\(f_{ij}\)表示第i个位置是j的情况数\(f_{ij}=\sum_v f_{i-1,v}-\sum_v f_{i-2,v}*max(0,k-v-j)\) 答案为\(f_{i+1,0}\)

CF1943E1

Alice每次选剩下的最少的数。Bob不会改变数的相对大小关系。

codes

A
点击查看代码
#include<iostream>
#include<cstdio>
#include<cstring>
#define I inline
using namespace std;

const int N = 200010;
int a[N],cnt[N];
int n; 

int main()
{
	int T; cin>>T;
	while(T--) {
		cin>>n;
		for(int i=1;i<=n;++i) cin>>a[i],cnt[a[i]]++;
		int ans=0,pd=1;
		for(int i=0;i<=n;++i) {
			if(cnt[i]==0) {
				ans=i;
				break;
			} else if(cnt[i]==1) {
				ans=i;
				if(pd) pd=0;
				else break;
			}
		}
		for(int i=1;i<=n;++i) cnt[a[i]]--;
		cout<<ans<<endl;
	}
 } 
B
点击查看代码
#include<iostream>
#include<cstdio>
#include<cstring>
#define I inline
#define int long long
using namespace std;

const int N = 401000;
char a[N],ra[N];
int l[N],cnt[N][27],lastpos[27],pre[N],sum2[N];
int n,rn,m;

I void predeal() {
	ra[1]='*';
	for(int i=1;i<=n;++i) ra[i*2]='|',ra[i*2+1]=a[i];
	ra[n*2+2]='|'; ra[n*2+3]='?';
	ra[n*2+4]=ra[n*2+5]=0;
	rn=n*2+3;
}
I void nanachar() {
	int mr=0,mid=0;
	for(int i=1;i<=rn;++i) l[i]=0;
	for(int i=1;i<=rn;++i) {
		if(i<mr) l[i]=min(l[mid*2-i],mr-i+1);
		while(ra[l[i]+i]==ra[i-l[i]]) l[i]++;
		if(i+l[i]-1>mr) mr=i+l[i]-1,mid=i;
	}
} 
signed main()
{
	int T; cin>>T;
	while(T--) {
		cin>>n>>m;
		scanf("%s",a+1);
		n=strlen(a+1);
		for(int i=1;i<=n;++i)
			for(int j=1;j<=26;++j) cnt[i][j]=0;
		for(int i=1;i<=n;++i) {
			for(int j=1;j<=26;++j) cnt[i][j]=cnt[i-1][j];
			cnt[i][a[i]-'a'+1]++;
		}
		for(int i=0;i<=n;++i) pre[i]=sum2[i]=0;
		memset(lastpos,0,sizeof(lastpos));
		for(int i=1;i<=n;++i) {
			int ch=a[i]-'a'+1;
			pre[i]=lastpos[ch];
			lastpos[ch]=i;
			sum2[i]+=(i-pre[i]==2);
		}
		for(int i=1;i<=n;++i) sum2[i]+=sum2[i-1];
		
		predeal(); nanachar();	
	//	cout<<(ra+1)<<endl;
	//	for(int i=1;i<=rn;++i) cout<<l[i]<<' '; cout<<endl;
		for(int i=1;i<=m;++i) {
			int L,R,nlen; scanf("%lld",&L); scanf("%lld",&R); nlen=R-L+1; 
			int ans=0;
			
			int mid=L+R+1,len=(ra[mid]>='a'&&ra[mid]<='z')+(l[mid]-1)/2*2;
		//	cout<<"waao"<<len<<endl;
			if(len<nlen) ans+=nlen;
		//	cout<<"ans1"<<ans<<endl;
			int ch=a[R]-'a'+1,flag1=0;
			if(cnt[R][ch]-cnt[L-1][ch]!=nlen&&nlen>=3) {
				int mlen;
				if(nlen%2) mlen=nlen-1;
				else mlen=nlen-2;
				ans+=mlen*(mlen/2+1)/2;
				flag1=1;
			}
			//cout<<"ans2"<<ans<<endl;
			if(flag1&&(nlen>=4&&sum2[R]-sum2[L+1]!=(R-(L+1)))) {
				int mlen;
				if(nlen%2) mlen=nlen-2;
				else mlen=nlen-1;
				ans+=(mlen+1)*((mlen-1)/2+1)/2-1;
			} 
			
			printf("%lld\n",ans);
		}	
	}
	
}
/*
2
7 1
aaaaaaa
1 7
8 1
aaaaaaaa
1 8
*/
C
点击查看代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#define I inline
using namespace std;

const int N = 20100;
vector<int> q[N],l;
int n,dep[N],f[N];

void dfs(int x,int fa) {
	f[x]=fa;
	dep[x]=dep[fa]+1;
	for(auto &t:q[x]) {
		if(t==fa) continue;
		dfs(t,x);
	}
}
int main()
{
	int T; cin>>T;
	while(T--) {
		cin>>n; l.clear();
		for(int i=1;i<=n;++i) q[i].clear();
		for(int i=1;i<n;++i) {
			int x,y; cin>>x>>y;
			q[x].push_back(y);
			q[y].push_back(x);
		}
		for(int i=1;i<=n;++i) dep[i]=0; 
		dfs(1,0);
		int mx1=1,mx2=1;
		for(int i=1;i<=n;++i) if(dep[i]>dep[mx1]) mx1=i;
		for(int i=1;i<=n;++i) dep[i]=0; 
		dfs(mx1,0);
		for(int i=1;i<=n;++i) if(dep[i]>dep[mx2]) mx2=i;
		while(1) {
			//cout<<mx2<<endl;
			l.push_back(mx2);
			mx2=f[mx2];
			if(!mx2) break;
		} //cout<<"sa";
		int len=l.size();// cout<<len<<endl;
		if(len%2) {
			cout<<len/2+1<<endl;
			for(int i=0;i<=len/2;++i) cout<<l[len/2]<<' '<<i<<endl;
		} else if(len%4==0){
			cout<<len/2<<endl;
			for(int i=1;i<=len/4;++i) cout<<l[len/2-1]<<' '<<i*2-1<<endl;
			for(int i=1;i<=len/4;++i) cout<<l[len/2]<<' '<<i*2-1<<endl;
		} else {
			cout<<len/2+1<<endl;
			for(int i=0;i<=len/2;++i) cout<<l[len/2]<<' '<<i<<endl;
		}
	}
}
D1
点击查看代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#define I inline
#define int long long
using namespace std;

const int N = 410;
signed f[N][N][N],sm[N][N][N];
int n,k;
int mod;

I void Mod(signed &x) {
	x=(x>=mod?x-mod:x);
}
I void LMod(int &x) {
	x=(x>=mod?x-mod:x);
}
signed main()
{
	int T; cin>>T;
	while(T--) {
		cin>>n>>k>>mod;
		for(int i=0;i<=n;++i)
			for(int j=0;j<=k;++j)
				for(int p=0;p<=k;++p)
					f[i][j][p]=sm[i][j][p]=0;
		for(int i=0;i<=k;++i)
			for(int j=i;j<=k;++j)
				f[2][i][j]=sm[2][i][j]=1;
		for(int j=0;j<=k;++j)
			for(int p=k-1;p>=0;--p)
				sm[2][p][j]=f[2][p][j]+sm[2][p+1][j],Mod(sm[2][p][j]);
		for(int i=3;i<=n;++i) {
			for(int j=0;j<=k;++j) {
				for(int p=0;p<=k;++p) {
					int mn=max(0ll,j-p);
					f[i][j][p]+=sm[i-1][mn][j];
					Mod(f[i][j][p]);
				}
			}
			for(int j=0;j<=k;++j) {
				sm[i][k][j]=f[i][k][j];
				for(int p=k-1;p>=0;--p) {
					sm[i][p][j]=f[i][p][j]+sm[i][p+1][j],Mod(sm[i][p][j]);
				}		
			}			
		}
		int sum=0;
		for(int i=0;i<=k;++i)
			for(int j=0;j<=i;++j)
				sum+=f[n][i][j],LMod(sum);
		cout<<sum<<endl;
	}
}
D2
点击查看代码
#include<iostream>
#include<cstdio>
#include<cstring>
#define I inline
#define int long long
using namespace std;

const int N = 3010;
int f[N][N],sm1[N][N],sm2[N][N];
int n,k,mod;

I void Mod(int &x) {
	x=(x>=mod?x-mod:x);
}
I void update(int x) {
	sm1[x][0]=f[x][0];
	for(int i=1;i<=k;++i) sm1[x][i]=f[x][i]+sm1[x][i-1],Mod(sm1[x][i]);
	for(int i=1;i<=k;++i) sm2[x][i]=f[x][i]*i%mod+sm2[x][i-1],Mod(sm2[x][i]);
}
signed main()
{
	int T; cin>>T;
	while(T--) {
		cin>>n>>k>>mod;
		for(int i=0;i<=n;++i)
			for(int j=0;j<=k;++j)
				f[i][j]=sm1[i][j]=sm2[i][j]=0;
		for(int i=0;i<=k;++i) f[1][i]=1;
		for(int i=0;i<=k;++i) f[2][i]=i+1;
		update(1); update(2);
		for(int i=3;i<=n+1;++i) {
			for(int j=0;j<=k;++j) {
				f[i][j]=sm1[i-1][k];
				int upper=k-j;
			//	cout<<"!!!"<<i<<' '<<j<<' '<<f[i][j]<<endl;
				f[i][j]+=sm2[i-2][upper]-sm1[i-2][upper]*(k-j+mod)%mod+mod;
				//if(lower!=0) f[i][j]-=sm2[i-2][lower-1]+(k-j+mod)*sm1[i-2][lower-1]%mod;
				f[i][j]=(f[i][j]%mod+mod)%mod;
			}
			update(i);
		}
//		for(int i=1;i<=n+1;++i)
//			for(int j=0;j<=k;++j) cout<<i<<' '<<j<<' '<<f[i][j]<<endl;
		cout<<sm1[n+1][0]<<endl;
	}
 } 
posted @ 2024-04-26 00:22  Kur0n1ko  阅读(33)  评论(0)    收藏  举报