CDQ分治

要求可以计算前面的操作对后面询问的贡献

BZOJ1176

#include <cstdio>
#include <algorithm>
using namespace std;

  int tr[2000001],p,ans[10001],s,q,opt,n,que;
  
  struct data1{
      int po,x,y,num,v,opt;
  }a[200001],tmp[200001];

  struct data{
      int num,po;
  }yt[200001];
  
  int mycomp(const data&a,const data&b){
      return(a.num<b.num);
  }

  int lowbit(int po){
      return(po&(-po));
  }

  int query(int po){
      int ret=0;
      for (;po;po-=lowbit(po)) ret+=tr[po];
      return(ret);
  }
  
  void add(int po,int num){
      for (;po<=p;po+=lowbit(po)) tr[po]+=num;
  }

  void solve(int l,int r){
      if (l==r) return;
      int mid=(l+r)>>1;
      solve(l,mid);solve(mid+1,r);
      int po=l;
      for (int i=mid+1;i<=r;i++)
        if (a[i].opt==2){
          while (po<=mid&&a[po].x<=a[i].x){
            if (a[po].opt==1) add(a[po].y,a[po].num);
          po++;    
        }
        ans[a[i].po]+=query(a[i].y)*a[i].v;    
      }
    for (int i=l;i<po;i++)
      if (a[i].opt==1) add(a[i].y,-a[i].num);
    
    int po1=l,po2=mid+1,po3=l;
    while (po1<=mid&&po2<=r){
      if (a[po1].x<a[po2].x) tmp[po3++]=a[po1++];else tmp[po3++]=a[po2++];
    }   
    while (po1<=mid) tmp[po3++]=a[po1++];
    while (po2<=r) tmp[po3++]=a[po2++];
    for (int i=l;i<=r;i++) a[i]=tmp[i];
  }

  int main(){
      scanf("%d%d",&s,&q);
      while (scanf("%d",&opt),opt!=3){
      if (opt==1){
          n++;
          a[n].opt=1;
          scanf("%d%d%d",&a[n].x,&yt[n].num,&a[n].num);
          yt[n].po=n;
      }else{
          int t1,t2,t3,t4;
        scanf("%d%d%d%d",&t1,&t2,&t3,&t4);
        que++;
        a[++n].po=que;a[n].v=1;a[n].x=t3;yt[n].num=t4;yt[n].po=n;a[n].opt=2;
        a[++n].po=que;a[n].v=-1;a[n].x=t1-1;yt[n].num=t4;yt[n].po=n;a[n].opt=2;
        a[++n].po=que;a[n].v=-1;a[n].x=t3;yt[n].num=t2-1;yt[n].po=n;a[n].opt=2;
        a[++n].po=que;a[n].v=1;a[n].x=t1-1;yt[n].num=t2-1;yt[n].po=n;a[n].opt=2;
      }
    }
    
    sort(yt+1,yt+n+1,mycomp);
    yt[0].num=-1e9;
    p=0;
    for (int i=1;i<=n;i++){
      if (yt[i].num!=yt[i-1].num) p++;
      a[yt[i].po].y=p;    
    }
    
    solve(1,n);
    
    for (int i=1;i<=que;i++) printf("%d
",ans[i]);
  }
原文地址:https://www.cnblogs.com/zhujiangning/p/6193744.html