Codeforces Contest 1062 problem C Banh-mi——莫队

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 n parts, places them on a row and numbers them from 1 through n. For each part i, he defines the deliciousness of the part as 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 i-th part then his enjoyment of the Banh-mi will increase by xi and the deliciousness of all the remaining parts will also increase by xi. The initial enjoyment of JATC is equal to 0.

For example, suppose the deliciousness of 3 parts are [0,1,0]. If JATC eats the second part then his enjoyment will become 1 and the deliciousness of remaining parts will become [1,,1]. Next, if he eats the first part then his enjoyment will become 2 and the remaining parts will become [,_,2]. After eating the last part, JATC’s enjoyment will become 4.

However, JATC doesn’t want to eat all the parts but to save some for later. He gives you q queries, each of them consisting of two integers li and ri. 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] 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+7.

Input
The first line contains two integers n and q (1≤n,q≤100000).

The second line contains a string of n characters, each character is either ‘0’ or ‘1’. The i-th character defines the deliciousness of the i-th part.

Each of the following q lines contains two integers li and ri (1≤li≤ri≤n) — the segment of the corresponding query.

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

Examples
inputCopy
4 2
1011
1 4
3 4
outputCopy
14
3
inputCopy
3 2
111
1 2
3 3
outputCopy
3
1
Note
In the first example:

For query 1: One of the best ways for JATC to eats those parts is in this order: 1, 4, 3, 2.
For query 2: Both 3, 4 and 4, 3 ordering give the same answer.
In the second example, any order of eating parts leads to the same answer.

题意:

给你一个串,分别由0和1组成,给你m个区间,问你这个区间内这个01串的最大值是多少,01串的值就是说,你拿掉位置x的值y,剩下的位置就会都加上y,比如说101,先拿掉第一个1,那么就变成1 12,在拿掉第二个,那么就变成1+2 3,最后答案就是6。

题解:

我们稍微模拟一下就会发现最大值是 2 区 间 中 1 的 个 数 − 1 + ( 2 区 间 中 1 的 个 数 − 1 ) ∗ ( 2 区 间 中 0 的 个 数 − 1 ) 2^{区间中1 的个数}-1+(2^{区间中1 的个数}-1)*(2^{区间中0的个数}-1) 211+211201,之后就是莫队了。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod=1e9+7;
int len;
const int N=1e5+5;
struct node
{
    int l,r,id;
}p[N];
ll ans[N],Pow[N];
int a[N];
int pos[N];
bool cmp(node a,node b)
{
    return pos[a.l]<pos[b.l]||pos[a.l]==pos[b.l]&&a.r<b.r;
}
void init()
{
    int ans=1;
    Pow[0]=1;
    for(ll i=1;i<N;i++)
        (ans*=2)%=mod,Pow[i]=ans%mod;
}
int main()
{
    init();
    int n,m;
    scanf("%d%d",&n,&m);
    blogs=(int)sqrt((double)m+0.1);
        for(ll i=1;i<=n;i++)
            pos[i]=(i-1)/blogs+1;
    for(int i=1;i<=n;i++)
        scanf("%1d",&a[i]);
    for(int i=1;i<=m;i++)
        scanf("%d%d",&p[i].l,&p[i].r),p[i].id=i;
    sort(p+1,p+1+m,cmp);
    int l=1,r=0;
    ll one=0;
    for(int i=1;i<=m;i++)
    {
        while(r<p[i].r)
            one+=a[++r];
        while(l>p[i].l)
            one+=a[--l];
        while(r>p[i].r)
            one-=a[r--];
        while(l<p[i].l)
            one-=a[l++];
        ans[p[i].id]=(Pow[one]-1+(Pow[one]-1)*(Pow[r-l+1-one]-1))%mod;
    }
    for(int i=1;i<=m;i++)
        printf("%lld\n",ans[i]);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值