Codeforces Round #781 (Div.2) A-E 完整题解

A. GCD vs LCM

意识到 n-3 1 1 1是一组解就行了~

复制代码
#include<bits/stdc++.h>
using namespace std;
typedef double db;
typedef long long ll;
const int N=200010;
int main(){
    int t;cin>>t;
    while(t--){
        int n;cin>>n;
        cout<<n-3<<' '<<1<<' '<<1<<' '<<1<<'\n';
    }
}
View Code
复制代码

B. Array Cloning Technique

很容易地意识到每次复制能让数组中出现次数最多的数倍增。而每次更换则是把数组中非最多的数换掉。

用map存一下,然后写个暴力就行啦~

复制代码
#include<bits/stdc++.h>
using namespace std;
typedef double db;
typedef long long ll;
const int N=200010;
int a[N];
int main(){
    int t;cin>>t;
    while(t--){
        int n;cin>>n;
        map<int,int>mp;
        for(int i=1;i<=n;i++){
            cin>>a[i];mp[a[i]]++;
        }
        int c=0;
        for(auto [_,cnt]:mp){
            c=max(c,cnt);
        }
        int ans=n-c;
        while(c<n){
            c*=2,ans++;
        }cout<<ans<<'\n';
    }
}
View Code
复制代码

C. Tree Infection

流汗黄豆题。

每天有两种操作:点杀、感染。

树上的儿子可以感染且至多至多感染另外一个儿子

那么显然的是,我们先把所有儿子从多到少感染一遍(包括0的儿子1)

然后考虑还需要几天全部感染完

接下来就是一个经典的二分问题了~

复制代码
#include<bits/stdc++.h>
using namespace std;
typedef double db;
typedef long long ll;
const int N=200010;
#define mid ((l+r)>>1)
int f[N],n;
int ch[N],cnt;
bool check(int x){
    int res=0;
    for(int i=1;i<=cnt;i++)res+=max(ch[i]-x,0);
    return (res<=x);
}
int main(){
    int t;cin>>t;
    while(t--){
        cin>>n;
        fill(ch,ch+n+5,0);
        for(int i=2;i<=n;i++)cin>>f[i],ch[f[i]]++;
        sort(ch+1,ch+n+1,greater<>());
        cnt=0;
        for(int i=1;i<=n;i++)cnt+=(ch[i]!=0);
        int ans=cnt+1;
        for(int i=1;i<=cnt;i++){
            ch[i]=max(0,ch[i]-(cnt+2)+i);
        }
        int res=0;
        int l=0,r=200010;
        while(l<=r){
            if(check(mid))res=mid,r=mid-1;
            else l=mid+1;
        }
        cout<<ans+res<<'\n';
    }
}
复制代码

D. GCD Guess

不妨设a<b

转化一下,每次询问的就是(b-a,x+a)了

考虑CRT是肯定不行的

然后我们注意到:当b-a=2的时候,询问出来的结果肯定是1或者2

考虑令a=1,b-a=2;于是发现,若询问答案是1,那么x+a是奇数,x%2=1;否则x+a是偶数,x%2=0;

然后我们就可以把握到,只要我们不断把a和b-a倍增,同时去掉x在低位上的影响,就可以把x的每一个二进制位都搞出来了

具体实现请看代码。

复制代码
#include<bits/stdc++.h>
using namespace std;
typedef double db;
typedef long long ll;
const int N=200010;
int wei[30];
int main(){
    int t;cin>>t;
    while(t--){
        int cnt=0;
        int x;
        for(int i=1;i<=30;i++){
            cout<<'?'<<' '<<(1<<(i-1))-cnt<<' '<<((1<<i)+(1<<(i-1)))-cnt<<endl;
            cin>>x;
            if(x==(1<<i))cnt+=(1<<(i-1));
        }
        cout<<'!'<<' '<<cnt<<endl;
    }
}
View Code
复制代码

E. MinimizOR

有好多做法,但我只会segtreeQAQ

 

posted @   笨竹子  阅读(84)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示