Codeforces Round #520 (Div. 2) C. Banh-mi

C. Banh-mi

time limit per test:1 second
memory limit per test:256 megabytes

题目链接https://codeforc.es/contest/1062/problem/C

Description:

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,1] . 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.

Input:

The first line contains two integers nn and qq (1n,q100000).

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 (1lirin) — the segment of the corresponding query.

Output:

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

Sample Input:

4 2
1011
1 4
3 4

Sample Output:

14
3

题意:

给出一个01串,每次可以选一个出来,然后其它的都会加上选出来的这个数。问怎么选可以让选出来的和最大。

题解:

首先肯定会选大的,然后会选小的。但是询问次数那么多,如果每次都通过模拟操作来实现,肯定会超时。

我们考虑每一个数给最终答案的贡献,比如有k个1,总长度为n。

选出第一个1,然后对答案的直接贡献是1,但是后面所有的都会加1,第二个1选出来的时候对答案的贡献会加1,然后这个1又会加到后面的数上,选后面的一个1时,对答案的贡献就是2了,然后以此类推...

最后会发现第一个1对最终答案的贡献就是2^(n-1),然后1的总贡献就时(2^(n-1)+2^(n-2)+...+2^(n-k)),最后再推下就可以得出最终答案了。

代码如下:

#include <cstdio>4 2
#include <cstring> 
#include <algorithm>
#include <iostream>
#define MOD 1000000007
using namespace std;

const int N = 1e5+5;
int n,q;
char s[N];
int len[N];

long long quick_pow(long long a,int b){
    long long ans=1;
    while(b){
        if(b&1) ans=(ans*a)%MOD;
        a=(a*a)%MOD;
        b>>=1;
    }
    return ans ;
}

int main(){
    scanf("%d%d",&n,&q);
    scanf("%s",s+1);
    for(int i=1;i<=n;i++) if(s[i]=='1') len[i]=len[i-1]+1;else len[i]=len[i-1];
    for(int i=1,l,r;i<=q;i++){
        scanf("%d%d",&l,&r);
        int len1 = len[r]-len[l-1],k=r-l+1;
        long long ans;
        ans=((quick_pow(2,len1)-1)%MOD*quick_pow(2,k-len1)%MOD)%MOD;
        printf("%lld\n",ans);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/heyuhhh/p/9986378.html