Sum Equals Xor(非常有意思的一道找规律的题)
题目描述
You are given a positive integer L in base two. How many pairs of non-negative integers (a,b) satisfy the following conditions?
·a+b≤L
·a+b=a XOR b
Since there can be extremely many such pairs, print the count modulo 10 9+7.
→What is XOR?
The XOR of integers A and B, A XOR B, is defined as follows:
·When A XOR B is written in base two, the digit in the 2 k’s place (k≥0) is 1 if either A or B, but not both, has 1 in the 2 k’s place, and 0 otherwise.
For example, 3 XOR 5=6. (In base two: 011 XOR 101=110.)
·a+b≤L
·a+b=a XOR b
Since there can be extremely many such pairs, print the count modulo 10 9+7.
→What is XOR?
The XOR of integers A and B, A XOR B, is defined as follows:
·When A XOR B is written in base two, the digit in the 2 k’s place (k≥0) is 1 if either A or B, but not both, has 1 in the 2 k’s place, and 0 otherwise.
For example, 3 XOR 5=6. (In base two: 011 XOR 101=110.)
Constraints
·L is given in base two, without leading zeros.
·1≤L<2100001
输入
Input is given from Standard Input in the following format:
L
输出
Print the number of pairs (a,b) that satisfy the conditions, modulo 10
9+7.
样例输入 Copy
【样例1】
10
【样例2】
1111111111111111111
样例输出 Copy
【样例1】
5
【样例2】
162261460
提示
样例1解释:Five pairs (a,b) satisfy the conditions: (0,0),(0,1),(1,0),(0,2) and (2,0).
首先打个表。
0 0 1
1 1 3
10 2 5
11 3 9
100 4 11
101 5 15
110 6 19
111 7 27
1000 8 29
1001 9 33
1010 10 37
1011 11 45
1100 12 49
1101 13 57
1110 14 65
1111 15 81
可以发现当最后一位为1,答案为前面的情况*3;
当最后一位为0.
1-10 ans+2
11-100 ans+=2
101-110 ans+=4
111-1000 ans+=2
1001-1010 ans+=4
1011-1100 ans+=8
1101-1110 ans+=8
后面分别为
2
4
4
8
4
8
8
16
由此可知,当答案不为3的倍数时,答案加上了一个2^j;
而这个j则为此时这个0前面1的个数。
再反推一下。当最后一位是1,答案等于前一位加上此时2^j(j为1的个数)
所以规律找到了。答案也快显然了。
然后让我们用dp思考。
dp[i][0]表示第i位的情况。
dp[i][1]前i位有多少个1.
dp[i][0]=dp[i-1][0]*3;
if(s[i]==1) {
dp[i][[1]=dp[i-1][1]*2;
dp[i][0]=dp[i-1][0]+dp[i][1];(算1xxxx0)
}
else dp[i][[1]=dp[i-1][1]
总答案为dp[n][1]+dp[n][0];
理解一下
上代码
#include<bits/stdc++.h>
#define rep(i , a , b) for(register int i=(a);i<=(b);i++)
#define rop(i , a , b) for(register int i=(a);i<(b);i++)
#define per(i , a , b) for(register int i=(a);i>=(b);i--)
#define por(i , a , b) for(register int i=(a);i>(b);i--)
using namespace std;
typedef long long ll;
const int mod=1000000007;
const int maxn = 1e5+10;
ll dp[maxn][2];
char s[maxn];
int main()
{
cin>>s+1;
dp[0][1]=1;
dp[0][0]=0;
ll n=strlen(s+1);
rep(i,1,n)
{
dp[i][0]=(dp[i-1][0]*3)%mod;
if(s[i]=='1'){
dp[i][1]=(dp[i-1][1]*2)%mod;
dp[i][0]+=dp[i-1][1];
dp[i][0]=(dp[i][0])%mod;
}
else{
dp[i][1]=dp[i-1][1];
}
}
printf("%lld\n",(dp[n][1]+dp[n][0])%mod);
}
非dp
#pragma GCC optimize(3 , "Ofast" , "inline")
#include <bits/stdc++.h>
#define rep(i , a , b) for(register int i=(a);i<=(b);i++)
#define rop(i , a , b) for(register int i=(a);i<(b);i++)
#define per(i , a , b) for(register int i=(a);i>=(b);i--)
#define por(i , a , b) for(register int i=(a);i>(b);i--)
using namespace std;
typedef long long ll;
typedef pair<int,int> pi;
const int mod = 1e9+7;
const int maxn = 1e5+10;
ll f[maxn];
void F() {
f[0]=1;
rep(i,1,maxn-5) f[i]=f[i-1]*3%mod;
}
template<class T>
inline void read(T &ret) {
char c;
ret=0;
while((c=getchar())<'0'||c>'9');
while(c>='0'&&c<='9') {
ret=ret*10+(c-'0'),c=getchar();
}
}
int main () {
string s;
cin>>s;
F ();
ll ans = 0;
ll t = 1;
int l = s.length ();
rep (i,0,l-1) {
if(s[i]=='1') {
ans=(ans+t*f[l-i-1]%mod)%mod;
t=t*2%mod;
}
}
ans+=t;
ans=ans%mod;
cout<<ans<<endl;
return 0;
}