E - Sum Equals Xor

176 阅读1分钟

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 500500 points

Problem Statement

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
  • �+�=� XOR �a+b=a XOR b

Since there can be extremely many such pairs, print the count modulo 109+7109+7.

Constraints

  • �L is given in base two, without leading zeros.
  • 1≤�<2100 0011≤L<2100 001

Input

Input is given from Standard Input in the following format:

�L

Output

Print the number of pairs (�,�)(a,b) that satisfy the conditions, modulo 109+7109+7.


Sample Input 1 Copy

Copy

10

Sample Output 1 Copy

Copy

5

Five pairs (�,�)(a,b) satisfy the conditions: (0,0),(0,1),(1,0),(0,2)(0,0),(0,1),(1,0),(0,2) and (2,0)(2,0).


Sample Input 2 Copy

Copy

1111111111111111111

Sample Output 2 Copy

Copy

162261460

中文大意

就是给你个数字X然你找到a + b = a ^ b && a + b <=x的总数 我们会发现a+b = a ^ b + (a & b) << 1这样我们就可以得出题目要求的是a & b == 0的条件&运算的话也就是如果两个数位不全是1就行所以根据这个条件我们可以进行数位dp这样我们就能求出正确的值了

Code

#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
#include <queue>
#include <vector>
#include <cmath>
#include <set>
#include <stack>
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
// #define int long long
#define endl '\n'
#define pb push_back
#define NO cout << "NO" << endl;
#define YES cout << "YES" << endl;
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,a,n) for (int i=n;i>=a;i--)
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<VI> VII;
ll MOD = 998244353;
ll powmod(ll a,ll b) {ll res=1;a%=MOD; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
mt19937 mrand(random_device{}()); 

const int mod = 1e9 + 7;
const int N  = 2e5 + 10;

int f[N], que[N], len;

int dfs(int pos, bool limit) {
   if (!pos) return 1;
   if (!limit && ~f[pos]) return f[pos];
   int res = 0;
   int up = limit ? que[pos] : 1;
   for (int i = 0; i <= up; i++) {
      (res += (i + 1ll) * dfs(pos - 1, limit && i == up) % mod) %= mod;
   }
   if (!limit) f[pos] = res;
   return res;
}

int main() {
   memset(f, -1, sizeof(f));
   string s; cin >> s;
   reverse(s.begin(), s.end());
   for(auto x : s) que[++len] = x - '0';
   int res =  dfs(len, true);
   printf("%d", res);
   return 0;
}