Codechef MONSTER 整体二分+分块

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

题意

有n个敌人,编号为0到n-1,每个敌人都有一个血量h。现在有q次操作,每次给出两个数x和y,表示将所有编号为x的子集(二进制下)的敌人血量都减去y。要求每次操作后输出还剩下多少个敌人的血量大于0。
n 2 17 , m 2 18 , h , y 10 9

分析

已经颓废到开始写题了。
首先可以整体二分(或者分块),然后就变成了子集加和单点查询问题,很容易想到分成前面9位和后面9位来做,这样复杂度就是 O ( n n l o g n ) ,然后极限爆过去了。

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>

typedef long long LL;

const int N=500005;
const int par1=(1<<9)-1;
const int par2=(1<<18)-1-par1;

int n,m,t[N],a[N],b[N],bin[20],ans[N],die[N],tmp[N];
LL h[N],w[N];

int read()
{
    int x=0,f=1;char ch=getchar();
    while (ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}

void add(int x,LL y)
{
    int p1=x&par1,p2=x&par2;
    for (int s=p2;s>=0;s=s?((s-1)&p2):s-1) w[s+p1]+=y;
}

LL query(int x)
{
    int p1=x&par1,p2=x&par2,p3=p1^par1;
    LL ans=0;
    for (int s=p3;s>=0;s=s?((s-1)&p3):s-1) ans+=w[s+p1+p2];
    return ans;
}

void solve(int l,int r,int L,int R)
{
    if (L>R) return;
    if (l==r)
    {
        for (int i=L;i<=R;i++)
            if ((t[i]&a[l])==t[i]&&b[l]>=h[t[i]]) die[t[i]]=l;
        return;
    }
    int mid=(l+r)/2;
    for (int i=l;i<=mid;i++) add(a[i],b[i]);
    int p=L,q=R;
    for (int i=L;i<=R;i++)
    {
        LL val=query(t[i]);
        if (val>=h[t[i]]) tmp[p++]=t[i];
        else h[t[i]]-=val,tmp[q--]=t[i];
    }
    for (int i=L;i<=R;i++) t[i]=tmp[i];
    for (int i=l;i<=mid;i++) add(a[i],-b[i]);
    solve(l,mid,L,p-1);solve(mid+1,r,q+1,R);
}

int main()
{
    bin[0]=1;
    for (int i=1;i<=18;i++) bin[i]=bin[i-1]*2;
    n=read();
    for (int i=0;i<n;i++) h[i]=read();
    m=read();
    for (int i=1;i<=m;i++) a[i]=read(),b[i]=read();
    for (int i=1;i<=n;i++) t[i]=i-1;
    solve(1,m,1,n);
    for (int i=0;i<n;i++) ans[die[i]]--;
    ans[1]+=n;
    for (int i=2;i<=m;i++) ans[i]+=ans[i-1];
    for (int i=1;i<=m;i++) printf("%d\n",ans[i]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_33229466/article/details/82260607
今日推荐