• 【思维】二进制模+预处理+暴力——atcoder AIsing Programming Contest 2020 D


    这题细节真的多。。但是思维性还是蛮强的

    一个数最多被操作logn次,所以可以预处理第一次操作,然后暴力解决

    分类讨论下修改1的情况和修改0的情况,处理出前缀和和后缀和即可

    #include<bits/stdc++.h>
    using namespace std;
    #define N 200005
    
    char a[N];
    int n,num,x,y,modx[N],mody[N],ans[N],pre[N],suf[N];
    
    
    int calc(int x){//把x除到0需要的步数 
        int res=0;
        while(x){
            res++;
            int tot=0;
            for(int i=0;(1<<i)<=x;i++)
                tot+=(x>>i & 1);
            x%=tot;
        } 
        return res;
    }
    
    int main(){
        cin>>n;
        cin>>(a+1);
        
        for(int i=1;i<=n;i++)
            if(a[i]=='1')num++;
        if(num==0){//没有1的时候 
            for(int i=1;i<=n;i++)cout<<1<<'
    ';
            return 0;
        }
        if(num==1){//只有一个1的时候 
            if(a[n]=='1')
                for(int i=1;i<=n;i++)ans[i]=(i==n?0:2); 
            else 
                for(int i=1;i<=n;i++){
                    if(a[i]=='1')ans[i]=0;
                    else if(i==n)ans[i]=2;
                    else ans[i]=1;
                }
            for(int i=1;i<=n;i++)cout<<ans[i]<<'
    ';
            return 0;
        }    
            
        
        x=num+1;y=num-1;//y>=1
        // 先把操作一次得到的结果求出来
         
        long long base=1;
        for(int i=n;i>=1;i--){
            base%=x;
            modx[i]=base;
            base*=2;
        }
        for(int i=1;i<=n;i++){
            if(a[i]=='1')pre[i]=modx[i]+pre[i-1];
            else pre[i]=pre[i-1];
            pre[i]%=x;
        }
        for(int i=n;i>=1;i--){
            if(a[i]=='1')suf[i]=modx[i]+suf[i+1];
            else suf[i]=suf[i+1];
            suf[i]%=x;
        }
        for(int i=1;i<=n;i++)if(a[i]=='0'){
            ans[i]=pre[i-1]+suf[i+1]+modx[i];
            ans[i]%=x;
        }
        
        base=1;
        for(int i=n;i>=1;i--){
            base%=y;
            mody[i]=base;
            base*=2;
        }
        for(int i=1;i<=n;i++){
            if(a[i]=='1')pre[i]=mody[i]+pre[i-1];
            else pre[i]=pre[i-1];
            pre[i]%=y;
        }
        for(int i=n;i>=1;i--){
            if(a[i]=='1')suf[i]=mody[i]+suf[i+1];
            else suf[i]=suf[i+1];
            suf[i]%=y;
        }
        for(int i=1;i<=n;i++)if(a[i]=='1'){
            ans[i]=pre[i-1]+suf[i+1];
            ans[i]%=y;
        }
         
        for(int i=1;i<=n;i++)
            cout<<calc(ans[i])+1<<'
    ';
    }
  • 相关阅读:
    用CSS开启硬件加速来提高网站性能
    vim中替换内容
    alias vi=vim
    PHP 多进程初识
    端口的查看
    PHP三种终止脚本执行:return,die,exit
    2021.3.14(每周总结)
    2021.3.13
    2021.3.12
    2021.3.11
  • 原文地址:https://www.cnblogs.com/zsben991126/p/13285912.html
Copyright © 2020-2023  润新知