The 2022 ICPC Asia Regionals Online Contest (I) A C D H

A 01 Sequence

对于每一个长度为3d的字符串 显然我们可以通过d个不连续的1来消去全部
但是连续的1显然是有贡献的 手动模拟一下我们就知道是\(\lceil n/2 \rceil\)
然后对于每一次询问 显然他的首尾可能相连
所以我们以0作为划分 找到离l最近的0(右边 找到离r最近的0(左边
可以二分 也可以直接用数组来做就是线性的
最后我们中间的一部分就直接前缀和求解
我们可以维护一个贡献度的前缀和 然后每个的贡献可以给这些个1中的任意一个位置即可
然后对于两边的1我们直接计算贡献相加即可

void solve() {
    int n,q;
    string s;
    cin>>n>>q>>s;
    s=')'+s;
    vector<int>a(n+10),sum(n+10),pre(n+10),nxt(n+10);
    int cnt=0;
    for(int i=1;i<=n;i++){
        if(s[i]=='1')cnt++;
        else cnt=0;
        pre[i]=cnt;
    }
    cnt=0;
    for(int i=n;i>=1;i--){
        if(s[i]=='1')cnt++;
        else cnt=0;
        nxt[i]=cnt;
    }
    for(int i=1;i<=n;i++)if(s[i]=='1')a[i]=1;
    for(int i=2;i<=n;i++)if(a[i-1]>=1&&a[i])a[i]=a[i-1]+1;
    for(int i=1;i<=n-1;i++)if(a[i+1]>a[i])a[i]=0;
    for(int i=1;i<=n;i++)if(a[i])a[i]=(a[i]+1)/2;
    for(int i=1;i<=n;i++)sum[i]=sum[i-1]+a[i];
    while(q--){
        int l,r;cin>>l>>r;
        cout<<max(0ll,(r-l+1)/3-(up(pre[r]+nxt[l],2)+sum[r-pre[r]]-sum[l+nxt[l]-1]))<<endl;
    }
}

C Delete the Tree

显然我们可以从上往下做
我们可以发现 只要是叶子节点都必须删掉
这样我们就直接计数叶子
注意特判只有一个节点的情况

void solve() {
    int n;cin>>n;
    if(n==1){cout<<1<<endl;return;}
    vector<int>d(n+1);
    for(int i=1;i<n;i++){
        int u,v;cin>>u>>v;
        d[u]++,d[v]++;
    }
    int ans=0;
    for(int i=1;i<=n;i++)if(d[i]==1)ans++;
    cout<<ans<<endl;
}

D Find the Number

我们发现最多的一个情况大概是C20 10=18w左右
所以情况不会太多 我们直接打表 二分即可

vector<int>v;
void dfs(int ans,int now,int pos){
    if(now==0){
        v.push_back(ans);
        return;
    }
    if(pos==30)return;
    if(now)dfs(ans+(1<<pos),now-1,pos+1);
    dfs(ans,now,pos+1);
}
void init(){
    v.push_back(2);
    for(int i=2;i<=15;i++){
        int ans=1<<i;
        //i+1 30-i-1
        dfs(ans,i-1,i+1);
    }
    std::sort(v.begin(), v.end());
    v.erase(unique(all(v)),v.end());
}
void solve() {
    int l,r;cin>>l>>r;
    int t= lower_bound(all(v),l)-v.begin();
    if(v[t]>=l&&v[t]<=r)cout<<v[t]<<endl;
    else cout<<-1<<endl;
}

H Step Debugging

每一个repeat 就相当于一个括号
a开头的library 和l开头的 其实都是一样的
所以我们在括号内就直接+ 遇到数字就是乘
当然times就相当于反括号
我们递归求解即可

int solve() {
    string s;
    int ans=0;
    while(cin>>s&&s!="fin"&&s!="times"){
        if(s[0]=='r')(ans+=solve())%=mod;
        else if(s[0]=='l'){(++ans)%=mod;}
        else if(s[0]>='0'&&s[0]<='9')(ans*=stoll(s))%=mod;
    }
    return ans%mod;
}
posted @ 2022-10-15 21:26  ycllz  阅读(40)  评论(0)    收藏  举报