Codeforces 1062C. Banh-mi(自认为找规律,推公式)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yuewenyao/article/details/88863088

题目

JATC loves Banh-mi (a Vietnamese food). His affection for Banh-mi is so much that he always has it for breakfast. This morning, as usual, he buys a Banh-mi and decides to enjoy it in a special way.

First, he splits the Banh-mi into nn parts, places them on a row and numbers them from 11 through nn. For each part ii, he defines the deliciousness of the part as xi∈{0,1}xi∈{0,1}. JATC's going to eat those parts one by one. At each step, he chooses arbitrary remaining part and eats it. Suppose that part is the ii-th part then his enjoyment of the Banh-mi will increase by xixi and the deliciousness of all the remaining parts will also increase by xixi. The initial enjoyment of JATC is equal to 00.

For example, suppose the deliciousness of 33 parts are [0,1,0][0,1,0]. If JATC eats the second part then his enjoyment will become 11 and the deliciousness of remaining parts will become [1,_,1][1,_,1]. Next, if he eats the first part then his enjoyment will become 22 and the remaining parts will become [_,_,2][_,_,2]. After eating the last part, JATC's enjoyment will become 44.

However, JATC doesn't want to eat all the parts but to save some for later. He gives you qq queries, each of them consisting of two integers lili and riri. For each query, you have to let him know what is the maximum enjoyment he can get if he eats all the parts with indices in the range [li,ri][li,ri] in some order.

All the queries are independent of each other. Since the answer to the query could be very large, print it modulo 109+7109+7.

Input

The first line contains two integers nn and qq (1≤n,q≤1000001≤n,q≤100000).

The second line contains a string of nn characters, each character is either '0' or '1'. The ii-th character defines the deliciousness of the ii-th part.

Each of the following qq lines contains two integers lili and riri (1≤li≤ri≤n1≤li≤ri≤n) — the segment of the corresponding query.

Output

Print qq lines, where ii-th of them contains a single integer — the answer to the ii-th query modulo 109+7109+7.

Examples

Input

4 2
1011
1 4
3 4

Output

14
3

Input

3 2
111
1 2
3 3

Output

3
1

Note

In the first example:

  • For query 11: One of the best ways for JATC to eats those parts is in this order: 11, 44, 33, 22.
  • For query 22: Both 33, 44 and 44, 33 ordering give the same answer.

In the second example, any order of eating parts leads to the same answer.

思路:我们可以先进行一个计算,如果先算0的话最后肯定是没有先算1的结果大。

         所以我们先求出每个位置 1 和 0  个数的前缀和,然后我们肯定要先干掉所有的1,然后我们再去处理0.

        所以:

                    我们假设有 x 个 1 , y 个 0

                       对于 1 来说,每一项是1   , 2   ,4     ,8              .............

                                                          2^0    2^1    2^2   2^3                            2^(n-1)

                                  等比数列,求和公式为:formula

                                   所以1的前n项和为 : Σ = (1*(1-2^x))  /  (1 - 2)     =     2^x - 1

                 对于0来说,每一项是0    ,     1     ,    3    ,     7  ................

                                                2^0-1    2^1-1    2^2-1    2^3 - 1    

                                            求和为:  Σ = ((2^x-1)*(1-2^y))  /  (1-2)  =      (2^x - 1) * (2^y - 1)

                     相加为 ------>   (2^x - 1) * (2^y - 1 + 1)   == (2^x-1)*y

     然后我们再进行查询的时候就是 O1 来查询了,还有个坑点,就是你在快速幂的时候要传入 mod 这个参数,然后对结果进行取余处理,我就是没有这样操作就一直wa3了,,,,,,

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<string>
using namespace std;
#define ll long long
const ll maxn = 1e6+5;
const ll mod = 1e9+7;

ll z[maxn] , y[maxn] , n , t;
string s;

int poww(ll a , ll b , ll m)
{
    ll ans = 1 ;
    ll base = a ;
    while(b != 0)
    {
        if(b & 1 != 0)
        ans = ans * base ;
        ans %= m;
            base *= base;
            base %= m;
            b >>= 1 ;
    }
    return ans % m;
}

int main()
{
  while(cin >> n >> t)
  {
    cin >> s;
    for(ll i = 0 ; i < n ; i ++)
    {
      if(s[i] == '1')
      {
        z[i+1] = z[i];
        y[i+1] = y[i] + 1;
      }
      else
      {
        z[i+1] = z[i] + 1;
        y[i+1] = y[i];
      }
    }
    while(t --)
    {
      ll a , b;
      cin >> a >> b;
      ll p = y[b] - y[a-1];
      ll q = z[b] - z[a-1];
      ll ans1 = (poww(2 , p , mod) - 1) % mod;
      ll ans2 = poww(2 , q , mod) % mod;
      ll ans = (ans1 * ans2) % mod;
      cout<<ans<<endl;
    }
  }
  return 0;
}

猜你喜欢

转载自blog.csdn.net/yuewenyao/article/details/88863088
今日推荐