answer:
1. For a number that is a multiple of 3 in decimal, its binary has a rule: the difference between the number of 1s in odd-numbered bits and the number of 1s in even-numbered bits is a multiple of 3.
2. Convert all 1s on even digits to -1, keep 1 on odd digits unchanged, and 0 on odd digits, and find the prefix sum.
The array a[i] represents the sum before the ith bit .
data | 1 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | —— |
a[i] | 0 | 1 | 0 | 0 | -1 | -1 | -2 | -1 | -1 |
3. If a[hi]-a[lo] is a multiple of 3 (including positive and negative), that is to say, the difference between the number of 1s on odd-numbered bits and the number of 1s on even-numbered bits is 3, then this section lo~hi String satisfies the condition.
4. Then for lo, hi, if a[lo]%3==a[hi]%3, then a[hi]-a[lo] must be a multiple of 3.
If a[hi]==-1, a[lo]==2, or a[hi]==-2, a[lo]==1, (lo and hi are interchangeable) also satisfy the situation. That is to say, for any a[i]<0, it can be regarded as a[i]+3.
5. Assuming that the number of the same prefix and modulo values is n, you only need to arbitrarily take two of them as lo and hi to satisfy the situation, so there are a total of Cn2 cases, and the accumulation of each modulo case is the answer .
#include <iostream> #include <stdio.h> #include <map> #include <queue> #include <string.h> #include <string> #include <stack> #include <cmath> #include <algorithm> using namespace std; typedef long long LL; char s[1000005]; LL a[1000005]; LL cnt[3]; int main(){ while(scanf("%s",s)!=EOF){ memset(a,0,sizeof(a)); memset(cnt,0,sizeof(cnt)); LL len=strlen(s); for(LL i=0;i<len;i++){ else if(s[i]=='1') a[i+1]=a[i]+1; else a[i+1]=a[i]; } for(LL i=0;i<=len;i++){ if(a[i]%3<0) cnt[a[i]%3+3]++; else cnt[a[i]%3]++; } LL ans=0; for(LL i=0;i<3;i++) ans+=cnt[i]*(cnt[i]-1)/2; printf("%lld\n",ans); } }