C. Banh-mi
题意
题
意
就
是
给
你
一
个
01
串
,
q
次
询
问
每
次
询
问
一
段
区
间
题意就是给你一个01串,q次询问每次询问一段区间
题意就是给你一个01串,q次询问每次询问一段区间
每
次
询
问
询
问
的
是
:
最
初
区
间
内
0
的
权
值
是
0
,
1
的
权
值
是
1
每次询问询问的是:最初区间内0的权值是0,1的权值是1
每次询问询问的是:最初区间内0的权值是0,1的权值是1
每
次
可
以
移
出
一
个
字
符
,
移
除
后
答
案
加
上
该
字
符
的
权
值
每次可以移出一个字符,移除后答案加上该字符的权值
每次可以移出一个字符,移除后答案加上该字符的权值
其
余
所
有
字
符
加
上
该
字
符
的
权
值
其余所有字符加上该字符的权值
其余所有字符加上该字符的权值
最
后
询
问
每
个
区
间
内
能
获
得
的
最
大
答
案
,
每
次
查
询
是
独
立
的
最后询问每个区间内能获得的最大答案,每次查询是独立的
最后询问每个区间内能获得的最大答案,每次查询是独立的
做法
首
先
我
们
发
现
,
对
每
个
区
间
来
说
,
一
定
是
一
直
拿
1
,
1
没
有
了
拿
0
这
个
策
略
首先我们发现,对每个区间来说,一定是一直拿1,1没有了拿0这个策略
首先我们发现,对每个区间来说,一定是一直拿1,1没有了拿0这个策略
所
以
问
题
就
变
为
给
你
一
个
先
1
后
0
的
序
列
来
计
算
上
面
的
问
题
所以问题就变为给你一个先1后0的序列来计算上面的问题
所以问题就变为给你一个先1后0的序列来计算上面的问题
而
这
个
序
列
中
0
,
1
的
个
数
我
们
都
可
以
通
过
前
缀
和
快
速
计
算
出
来
而这个序列中0,1的个数我们都可以通过前缀和快速计算出来
而这个序列中0,1的个数我们都可以通过前缀和快速计算出来
我
们
发
现
对
于
每
个
1
的
区
间
,
对
答
案
的
贡
献
是
一
段
首
项
为
1
我们发现对于每个1的区间,对答案的贡献是一段首项为1
我们发现对于每个1的区间,对答案的贡献是一段首项为1
公
比
为
2
,
长
度
为
1
的
个
数
等
比
数
列
公比为2,长度为1的个数等比数列
公比为2,长度为1的个数等比数列
对
于
每
个
0
的
区
间
,
对
答
案
的
贡
献
是
一
段
首
项
为
1
那
段
区
间
对
答
案
的
贡
献
对于每个0的区间,对答案的贡献是一段首项为1那段区间对答案的贡献
对于每个0的区间,对答案的贡献是一段首项为1那段区间对答案的贡献
公
比
为
2
,
长
度
为
0
的
个
数
的
等
比
数
列
公比为2,长度为0的个数的等比数列
公比为2,长度为0的个数的等比数列
之
后
加
个
快
速
幂
再
加
个
前
缀
和
预
处
理
这
道
题
就
做
完
了
“
”
之后加个快速幂再加个前缀和预处理这道题就做完了“”
之后加个快速幂再加个前缀和预处理这道题就做完了“”
坑点
有 减 法 要 加 M o d 有减法要加Mod%Mod 有减法要加Mod
代码
#include<iostream>
#include<math.h>
#include<stdio.h>
#include<algorithm>
#include<queue>
#include<map>
#include<bitset>
#include<stack>
#include<set>
#include<vector>
#include <time.h>
#include<string.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <ll, int> pli;
typedef pair <db, db> pdd;
const int maxn = 1e5+5;
const int Mod=1000000007;
const int INF = 0x3f3f3f3f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const double e=exp(1);
const db PI = acos(-1);
const db ERR = 1e-10;
#define Se second
#define Fi first
#define pb push_back
#define dbg(x) cout<<#x<<" = "<< (x)<< endl
#define dbg2(x1,x2) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<endl
#define dbg3(x1,x2,x3) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<" "<<#x3<<" = "<<x3<<endl
ll pow_(ll a,ll b)
{
ll ans=1;
while(b)
{
if(b&1) ans=(ans*a)%Mod;
b>>=1;
a=(a*a)%Mod;
}
return ans;
}
ll inv(ll x)
{
return pow_(x,Mod-2);
}
ll sum[maxn][2];
char str[maxn];
int main()
{
//ios::sync_with_stdio(false);
//freopen("a.txt","r",stdin);
//freopen("b.txt","w",stdout);
int n,q;
scanf("%d%d",&n,&q);
scanf("%s",str+1);
for(int i=1;i<=n;i++)
{
sum[i][0]=sum[i-1][0];
sum[i][1]=sum[i-1][1];
if(str[i]=='0') sum[i][0]=(sum[i][0]+1)%Mod;
else sum[i][1]=(sum[i][1]+1)%Mod;;
}
while(q--)
{
int l,r;
scanf("%d%d",&l,&r);
ll sum0=(sum[r][0]-sum[l-1][0]+Mod)%Mod;
ll sum1=(sum[r][1]-sum[l-1][1]+Mod)%Mod;
ll ans=0;
ans=(pow_(2,sum1)-1+Mod)%Mod;
ll st=(pow_(2,sum1)-1+Mod)%Mod;
ll tmp=(pow_(2,sum0)-1+Mod)%Mod;
tmp=(tmp*st)%Mod;
ans=(ans+tmp)%Mod;
printf("%lld\n",ans);
}
//cout << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
return 0;
}