HUST 1599 Multiple

来源:互联网 发布:全国网络教育阳光招生服务平台 编辑:程序博客网 时间:2024/05/17 21:41

Description

Rocket323 loves math very much. One day, Rocket323 got a number string. He could choose some consecutive digits from the string to form a number. Rocket323 loves 64 very much, so he wanted to know how many ways can he choose from the string so the number he got multiples of 64 ? 
  
A number cannot have leading zeros. For example, 0, 64, 6464, 128 are numbers which multiple of 64 , but 12, 064, 00, 1234 are not. 

Input

Multiple cases, in each test cases there is only one line consist a number string. 
Length of the string is less than 3 * 10^5 . 
  
Huge Input , scanf is recommended. 

Output

Print the number of ways Rocket323 can choose some consecutive digits to form a number which multiples of 64. 

Sample Input

64064

Sample Output

5

Hint

There are five substrings which multiples of 64. 
[64]064 
640[64] 
64[0]64 
[64064] 

[640]64 


这里提供两种思路,一种是对于64取模总共就64种状态,那么只要开一个64的数组每次递推记录下从第i位(i<=j)到第j位的数字对于64取模的答案即可。

#include<cstdio>#include<vector>#include<cstring>#include<algorithm>using namespace std;typedef long long LL;const int maxn=3e5+10;LL f[2][65],ans;int flag;char s[maxn];int main(){while (~scanf("%s",s)){int now=ans=0;for (int i=0;i<64;i++) f[0][i]=f[1][i]=0;for (int i=flag=0;s[i];i++,now^=1){int k=s[i]-'0';for (int j=0;j<64;j++) f[now^1][j]=0;for (int j=0;j<64;j++) f[now^1][(j*10+k)%64]+=f[now][j];if (k) f[now^1][k]++; else flag++;ans+=f[now^1][0];}printf("%lld\n",ans+flag);}return 0;}

另一种想法是64是2^6,也就是说10^6对于64取模为0,那么每次保存6位对于64取模的答案,然后统计之前的0的个数减掉就好了。

#include<cstdio>#include<string>#include<cstring>#include<vector>#include<iostream>#include<queue>#include<map>#include<bitset>#include<algorithm>using namespace std;typedef long long LL;const int INF = 0x7FFFFFFF;const int mod = 1e9 + 7;const int maxn = 3e5 + 10;int a[maxn] = { 100000, 10000, 1000, 100, 10, 1 };int cnt[maxn];char s[maxn];int main(){while (scanf("%s", s) != EOF){LL ans = 0, now = cnt[0] = 0;for (int i = 0; s[i]; i++){if (s[i] == '0') cnt[i] = cnt[max(0, i - 1)] + 1; else cnt[i] = cnt[max(0, i - 1)];now = (now * 10 + s[i] - '0') % 1000000;if (now % 64 == 0 && i >= 6) ans += i - 6 + 1 - cnt[i - 6];for (int j = 0, k = now; j < 6; j++){if (!(k / a[j])) continue;if (k % 64 == 0) ans++; k %= a[j];}}printf("%lld\n", ans + cnt[strlen(s) - 1]);}return 0;}


0 0