P3527 [POI2011]MET-Meteors 整体二分

  给定一个环,每个节点有一个所属国家,k次事件,每次对[l,r]区间上的每个点点权加上一个值,求每个国家最早多少次操作之后所有点的点权和能达到一个值

非常好的整体二分模板题

之前的修改和询问都是全部扔到结构体里面一起分治的 这题不用这样(因为是先修改后询问的) 所以只对询问进行分治即可 可以减少很多码量 (但之前的模板题不适合这样   之前二分的为值域 如果遍历值域的话复杂度太高了   这题二分的不是自然数值域 而是操作次数!)

注意给定的是一个环  所以当处理左端点大于右端点的区间时  将右端点加上区间长度(也就是展开成一条链 ) 同时在树状数组询问的时候要加上两个值(一个值比另一个大m)

二分的右界+1 当均不满足的时候 跳到右界+1

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define ll long long
#define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
#define inf 0x3f3f3f3f
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
const int N=2e6+10;
int n,m,ans[N],zuo[N],you[N],pos,head[N],k,x;
ll v[N],t[N];
struct Edge{int to,nex;}edge[N<<1];
void add(int a,int b){edge[++pos]=(Edge){b,head[a]};head[a]=pos;}
void upnode(int x,int v){for(;x<=N;x+=x&-x)t[x]+=v;}
ll qsum(int x){ll ans=0;for(;x;x-=x&-x)ans+=t[x];return ans;}
struct node{ll id,need;}s[N],temp1[N],temp2[N];

void solve(int L,int R,int l,int r)
{
    if(l>r)return ;
    if(L==R){rep(i,l,r)ans[s[i].id]=L;return ;}
    int mid=(L+R)>>1;
    rep(i,L,mid)upnode(zuo[i],v[i]),upnode(you[i]+1,-v[i]);
    int cnt1=0,cnt2=0;
    rep(i,l,r)
    {    
        ll sum=0;
        for(int j=head[s[i].id];j&&sum<=s[i].need;j=edge[j].nex)
        sum+=qsum(edge[j].to)+qsum(edge[j].to+m);
        if(sum>=s[i].need)temp1[++cnt1]=s[i];
        else temp2[++cnt2]=s[i],temp2[cnt2].need-=sum;
    }
    rep(i,L,mid)upnode(zuo[i],-v[i]),upnode(you[i]+1,v[i]);//谁污染谁治理
    
    rep(i,1,cnt1)s[l-1+i]=temp1[i];
    rep(i,1,cnt2)s[l+cnt1-1+i]=temp2[i];
    solve(L,mid,  l,l+cnt1-1);solve(mid+1,R,l+cnt1,r);
}
int main()
{
    scanf("%d%d",&n,&m);
    rep(i,1,m)scanf("%d",&x),add(x,i);
    rep(i,1,n)scanf("%lld",&s[i].need),s[i].id=i;
    scanf("%d",&k);
    rep(i,1,k){scanf("%d%d%lld",&zuo[i],&you[i],&v[i]);if(you[i]<zuo[i])you[i]+=m;}
    solve(1,k+1,1,n);
    rep(i,1,n)
    if(ans[i]==k+1)printf("NIE
");
    else printf("%d
",ans[i]);
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/bxd123/p/11547889.html