1. 程式人生 > >Codeforces Round #520 (Div. 2) C. Banh-mi

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

force 貢獻 模擬操作 idt ant pow rac range for each

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

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