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

一个数最多被操作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<<'\n';
        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]<<'\n';
        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<<'\n';
}

 

相关文章:

  • 2021-12-21
  • 2022-02-28
  • 2021-12-05
  • 2021-12-26
  • 2022-12-23
  • 2022-03-07
  • 2022-12-23
  • 2021-09-27
猜你喜欢
  • 2021-08-19
  • 2021-05-18
  • 2021-11-18
  • 2021-09-27
  • 2021-12-19
  • 2021-12-15
  • 2022-12-23
相关资源
相似解决方案