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
For example, suppose the deliciousness of 33 parts are [0,1][0,1] . If JATC eats the second part then his enjoyment will become
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 (1≤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≤n) — 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