CF1328
CF1328A
如果 \(a\) 是 \(b\) 的倍数 输出0
否则二分答案
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define inl inline
#define ll long long
#define endl '\n'
#define int ll
const int N=3e6+5;
const int M=1e5+5;
const int inf=0x3f3f3f3f3f3f3f3f;
const int base=131;
const int mod=1e9+7;
inl int read(){
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
inl void write(int x){
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
}
inl void writei(int x){write(x);putchar(' ');}
inl void writel(int x){write(x);putchar(endl);}
int t,n,m,a,b;
signed main(){
t=read();
while(t--){
a=read();b=read();
if(!(a%b)){writel(0);continue;}
int l=0,r=1e9,ans;
while(l<=r){
int mid=l+r>>1;
if(mid*b>a)ans=mid*b-a,r=mid-1;
else l=mid+1;
}
writel(ans);
}
return 0;
}
CF1328B
考虑两个 \(b\) 位置
bb
bab bba
baab baba bbaa
发现数量为1+2+...+x
可以二分第一个b位置 第二个就是剩下的数量
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define inl inline
#define ll long long
#define endl '\n'
#define int ll
const int N=3e6+5;
const int M=1e5+5;
const int inf=0x3f3f3f3f3f3f3f3f;
const int base=131;
const int mod=1e9+7;
inl int read(){
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
inl void write(int x){
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
}
inl void writei(int x){write(x);putchar(' ');}
inl void writel(int x){write(x);putchar(endl);}
int t,n,k,a,b;
signed main(){
t=read();
while(t--){
n=read();k=read();
int l=0,r=n-1,ans;
while(l<=r){
int mid=l+r>>1;
if(mid*(mid+1)/2<k)ans=mid,l=mid+1;
else r=mid-1;
}
int lp=n-ans-1,rp=n-(k-ans*(ans+1)/2)+1;
for(int i=1;i<=n;i++)putchar(i==lp||i==rp?'b':'a');putchar(endl);
}
return 0;
}
CF1328C
贪心。
前面尽量均摊 出现1之后就尽量让a为0 这样最优
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define inl inline
#define ll long long
#define endl '\n'
#define int ll
const int N=3e6+5;
const int M=1e5+5;
const int inf=0x3f3f3f3f3f3f3f3f;
const int base=131;
const int mod=1e9+7;
inl int read(){
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
inl void write(int x){
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
}
inl void writei(int x){write(x);putchar(' ');}
inl void writel(int x){write(x);putchar(endl);}
int t,n,k;
string a,b,c;
signed main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>t;
while(t--){
cin>>n>>c;
a.clear(),b.clear();
int flag=1;
for(auto i:c){
if(flag){
if(i=='2')a+='1',b+='1';
if(i=='0')a+='0',b+='0';
if(i=='1')a+='1',b+='0',flag=0;
}else{
if(i=='2')a+='0',b+='2';
if(i=='0')a+='0',b+='0';
if(i=='1')a+='0',b+='1';
}
}
cout<<a<<endl<<b<<endl;
}
return 0;
}
CF1328D
贪心。
都一样全填1.
n偶数121212...
n奇数找是否有相邻的相同 这样让相邻11 其余1212
否则123123...
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define inl inline
#define ll long long
#define endl '\n'
#define int ll
const int N=3e6+5;
const int M=1e5+5;
const int inf=0x3f3f3f3f3f3f3f3f;
const int base=131;
const int mod=1e9+7;
inl int read(){
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
inl void write(int x){
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
}
inl void writei(int x){write(x);putchar(' ');}
inl void writel(int x){write(x);putchar(endl);}
int t,n,a[N],b[N];
signed main(){
t=read();
while(t--){
n=read();
for(int i=1;i<=n;i++)a[i]=b[i]=read();
sort(b+1,b+n+1);
int m=unique(b+1,b+n+1)-b-1;
if(m==1){
writel(1);
for(int i=1;i<=n;i++)writei(1);putchar(endl);
continue;
}
if(!(n&1)){
writel(2);
for(int i=1;i<=n;i++)writei(i&1?1:2);putchar(endl);
continue;
}
for(int i=1;i<=n;i++)a[i]=lower_bound(b+1,b+m+1,a[i])-b;
int flag=a[1]==a[n],pos=flag?1:0;
for(int i=2;i<=n;i++){
if(flag)break;
flag|=a[i]==a[i-1];
pos=flag?i:0;
}
if(flag){
writel(2);
for(int cnt=1,i=pos;cnt<=n;cnt++,i++){
if(i>n)i-=n;
a[i]=cnt&1?1:2;
}
for(int i=1;i<=n;i++)
writei(a[i]);putchar(endl);
}else{
writel(3);
for(int i=1;i<=n-(n%3);i++)
writei(((i-1)%3)+1);
if(n%3==1)writei(2);
if(n%3==2)writei(1),writei(2);
putchar(endl);
}
}
return 0;
}
CF1328E
发现只要保证这些点父亲在一条链上即可
暴力lca判断即可
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define inl inline
#define ll long long
#define endl '\n'
#define int ll
const int N=3e6+5;
const int M=1e5+5;
const int inf=0x3f3f3f3f3f3f3f3f;
const int base=131;
const int mod=1e9+7;
inl int read(){
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
inl void write(int x){
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
}
inl void writei(int x){write(x);putchar(' ');}
inl void writel(int x){write(x);putchar(endl);}
int n,m,k,head[N],to[N],nxt[N],cnt;
inl void add(int u,int v){
nxt[++cnt]=head[u];
to[cnt]=v;
head[u]=cnt;
}
int dep[N],f[N][22];
vector<int>v;
inl void dfs(int x,int fa){
f[x][0]=fa;dep[x]=dep[fa]+1;
for(int i=1;i<=20;i++)f[x][i]=f[f[x][i-1]][i-1];
for(int i=head[x];i;i=nxt[i]){
int y=to[i];
if(y==fa)continue;
dfs(y,x);
}
}
inl bool find(int x,int y){
for(int i=20;~i;i--){
if(dep[f[x][i]]<dep[y])continue;
x=f[x][i];
}
return x==y;
}
inl bool cmp(int a,int b){return dep[a]<dep[b];}
signed main(){
n=read();m=read();
for(int i=1;i<=n-1;i++){
int u=read(),v=read();
add(u,v);add(v,u);
}dfs(1,0);
while(m--){
k=read();int ans=1;v.clear();
for(int i=1;i<=k;i++)v.push_back(f[read()][0]);
sort(v.begin(),v.end(),cmp);
for(int i=1;i<k;i++)ans&=find(v[i],v[i-1]);
puts(ans?"YES":"NO");
}
return 0;
}
CF1328F
每次一定让其全变成原序列中某个数最优
排序后维护前后缀和 那么枚举每个位置 可以 \(O(1)\) 求出答案
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define inl inline
#define ll long long
#define endl '\n'
#define int ll
const int N=4e5+5;
const int M=1e5+5;
const int inf=0x3f3f3f3f3f3f3f3f;
const int base=131;
const int mod=1e9+7;
inl int read(){
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
inl void write(int x){
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
}
inl void writei(int x){write(x);putchar(' ');}
inl void writel(int x){write(x);putchar(endl);}
int n,k,a[N],pre[N],suf[N],ans=inf,res;
signed main(){
n=read();k=read();
for(int i=1;i<=n;i++)a[i]=read();
sort(a+1,a+n+1);
int cnt=1;
for(int i=2;i<=n;i++){
if(a[i]^a[i-1])res=max(res,cnt),cnt=1;
else cnt++;
}res=max(res,cnt);
if(res>=k){puts("0");return 0;}
for(int i=1;i<=n;i++)pre[i]=pre[i-1]+a[i];
for(int i=n;i;i--)suf[i]=suf[i+1]+a[i];
for(int i=1;i<=n;i++){
if(i>=k)ans=min(ans,i*a[i]-pre[i]-(i-k));
else ans=min(ans,(2*i-n-1)*a[i]-pre[i]+suf[i]-(n-k));
if(n-i+1>=k)ans=min(ans,suf[i]-(n-i+1)*a[i]-(n-i+1-k));
else ans=min(ans,(2*i-n-1)*a[i]-pre[i]+suf[i]-(n-k));
}
writel(ans);
return 0;
}