Sum Equals Xor(非常有意思的一道找规律的题)

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.)

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;
}

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值