Codeforces Round 934 (Div. 1)
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;
}
}

浙公网安备 33010602011771号