codeforces 1062C. Banh-mi

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

传送门:http://codeforces.com/problemset/problem/1062/C

思路:先求出每个位置1和0个数的前缀和,肯定先干掉所有的1,再搞0,。所以可以这样推↓

于是就可以O1查询了!

代码:

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<string>
#include<iostream>
#include<map>
#include<vector>
#include<set>
#include<queue>
using namespace std;
typedef long long ll;
const ll maxv=1e5+5;
const ll mod=1e9+7;

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

string s;
ll zero[maxv],one[maxv];

int main()
{
	ll n,q;
	cin>>n>>q;
	zero[0]=one[0]=0;
	cin>>s;
	for(ll i=0;i<n;i++)
	{
		if(s[i]=='1')
		{
			zero[i+1]=zero[i];
			one[i+1]=one[i]+1;
		}
		else
		{
			zero[i+1]=zero[i]+1;
			one[i+1]=one[i];
		}
	}
	while(q--)
	{
		ll st,ed;
		cin>>st>>ed;
		ll x=one[ed]-one[st-1];
		ll y=zero[ed]-zero[st-1];
		ll ans=((quick_pow(2,x,mod)-1)*quick_pow(2,y,mod))%mod;
		cout<<ans<<endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_39396954/article/details/84135067