1. 程式人生 > 實用技巧 >D - Anything Goes to Zero(快速冪,__builtin_popcount())

D - Anything Goes to Zero(快速冪,__builtin_popcount())

題目連結:https://atcoder.jp/contests/aising2020/tasks/aising2020_d

題意:對輸入的二進位制串x,設它每一位分別取反後的十進位制結果為f,二進位制的f中1的個數為n,令f=f%n,輸出使f=0需要經過該操作的次數。

程式碼:

#include<bits/stdc++.h>
using namespace std;
#define ll long long

//簡便快速冪
ll power(ll a,ll b,ll mod){
    return b?power(a*a%mod,b/2,mod)*(b%2?a:1)%mod:1;
}

ll cal(ll n){
    ll cnt
=1; while(n){ n=n%__builtin_popcount(n); cnt++; } return cnt; } int main(){ int n;cin>>n; string x;cin>>x; ll ans1=0,ans2=0,cnt=0,ans; for(int i=0;i<n;i++){ if(x[i]=='1') cnt++; } if(cnt>1){ for(int i=0;i<n;i++)
if(x[i]=='1'){ ans1=(ans1+power(2,n-i-1,cnt+1))%(cnt+1),ans2=(ans2+power(2,n-i-1,cnt-1))%(cnt-1); } for(int i=0;i<n;i++){ if(x[i]=='1'){ ans=(ans2+((cnt-1)-power(2,n-i-1,cnt-1)%(cnt-1))%(cnt-1))%(cnt-1); cout<<cal(ans)<<endl; }
else{ //cout<<ans1; ans=(ans1+power(2,n-i-1,cnt+1)%(cnt+1))%(cnt+1); //cout<<' '<<ans<<endl; cout<<cal(ans)<<endl; } } } else if(cnt){ for(int i=0;i<n;i++) if(x[i]=='1') ans1=power(2,n-i-1,cnt+1)%(cnt+1); for(int i=0;i<n;i++){ if(x[i]=='0'){ ans=(ans1+power(2,n-i-1,cnt+1)%(cnt+1))%(cnt+1); cout<<cal(ans)<<endl; } else{ cout<<'0'<<endl; } } } else{ for(int i=0;i<n;i++) cout<<'1'<<endl; } return 0; }