首页 > 其他 > 详细

AIsing Programming Contest 2020 D - Anything Goes to Zero

时间:2020-07-14 14:50:22      阅读:65      评论:0      收藏:0      [点我收藏+]

题目链接:https://atcoder.jp/contests/aising2020/tasks/aising2020_d

题意:给一个位数为 1~2e5的 数  (可能有前置0)定义f(x)为x对popcount(x) 取模  每一位都要取反一次,(进行到下一位的时候,上面恢复原样)

问没一位数要 f 几次

思路:首先考虑大数的问题,开始去找 几个1 和取模的数有无规律 发现没有

那么就要处理掉这个大数,肯定是要通过取模来使得数变小,并且取模的数是固定的  假设sum为字符串中1的总数 那么取模要么是sum-1 要么就是sum+1 对应1和0

那么就可以处理出  sum1 为取模后的大数的值,sum0 也为取模后的大数的值  在遍历字符串的时候 遇到1 用sum1 减去当前的值即可, 遇到0 用sum0+上当前的值即可

因为f 函数 每次取模后剩下的都是1的个数以内的数 所以复杂度是logn 以内的

唯一要注意的就是 sum-1 为0时要讨论以下, 不能对0取模

技术分享图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define ull unsigned long long
 5 #define pb push_back
 6 const int maxn=2e5+10;
 7 const int mod=1e9+7;
 8 char s[maxn];
 9 vector<int>ans;
10 int f(int x)
11 {
12     int cnt=0;
13     while(x)
14     {
15         x%=__builtin_popcount(x);
16         cnt++;
17     }
18     return cnt+1;
19 }
20 ll power(ll base,ll n,ll m)
21 {
22     ll r=1;
23     while(n)
24     {
25         if(n&1) r=r*base%m;
26         base=base*base%m;
27         n/=2;
28     }
29     return r;
30 }
31 
32 int main()
33 {
34     ios::sync_with_stdio(false);
35     cin.tie(0);
36     int n;
37     cin>>n;
38     cin>>(s+1);
39     int sum=0;
40     for(int i=1;i<=n;i++)
41     {
42         if(s[i]==1)
43             sum++;
44     }
45     ll sum1=0;
46     ll sum0=0;
47     reverse(s+1,s+1+n);
48     for(int i=1;i<=n;i++)
49     {
50         if(s[i]==1)
51         {
52             sum0+=power(2,i-1,sum+1);
53             sum0%=(sum+1);
54             if(sum-1==0)
55                 continue;
56             sum1+=power(2,i-1,sum-1);
57             sum1%=(sum-1);
58 
59         }
60     }
61     for(int i=1;i<=n;i++)
62     {
63         if(s[i]==1)
64         {
65             if(sum-1==0)
66             {
67                 ans.pb(0);
68                 continue;
69             }
70             ll temp=sum1-power(2,i-1,sum-1);
71             temp=(temp+sum-1)%(sum-1);
72             ans.pb(f(temp));
73         }
74         else
75         {
76             ll temp=sum0+power(2,i-1,sum+1);
77             temp%=sum+1;
78             ans.pb(f(temp));
79         }
80     }
81     reverse(ans.begin(),ans.end());
82     for(auto &v:ans)
83         cout<<v<<\n;
84 
85 
86 
87 
88 
89 
90 
91 
92 
93 }
View Code

 

AIsing Programming Contest 2020 D - Anything Goes to Zero

原文:https://www.cnblogs.com/winfor/p/13298490.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!