区间修改区间求和cdq分治

https://www.luogu.org/problemnew/show/P3372

#include<bits/stdc++.h>
#define fi first
#define se second
#define INF 0x3f3f3f3f
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pqueue priority_queue
#define NEW(a,b) memset(a,b,sizeof(a))
#define lowbit(x) (x&(-x))
#define si(x) scanf("%d",&x)
#define sl(x) scanf("%lld",&x)
#define lc (d<<1)
#define rc (d<<1|1)
const double pi=4.0*atan(1.0);
const double e=exp(1.0);
const int maxn=1e5+8;
typedef long long LL;
typedef unsigned long long ULL;
const LL mod=1e9+7;
const ULL base=1e7+7;
using namespace std;
struct node{
    int type,x,st;
    LL v;
    bool operator<(const node &t) const{
        return x==t.x?type<t.type:x<t.x;
    }
}q[maxn<<2],temp[maxn<<2];
LL ans[maxn];
LL pre[maxn];
void cdq(int l,int r){
    if(l==r) return ;
    //cout<<l<<' '<<r<<endl;
    int mid=(l+r)>>1;
    cdq(l,mid);cdq(mid+1,r);
    int i=l,j=mid+1,p=l;
    LL now=0,val=0;
    int last=0;
    while(i<=mid||j<=r){
        if(j>r||(i<=mid&&q[i]<q[j]) ){
            now+=(q[i].x-last)*val; last=q[i].x;
            if(q[i].type==1) val+=q[i].v;
            temp[p++]=q[i++];
        }
        else{
            now+=(q[j].x-last)*val; last=q[j].x;
            if(q[j].type==2) ans[q[j].st]+= now*q[j].v;
            temp[p++]=q[j++];
        }
    }
    for(int i=l;i<=r;i++) q[i]=temp[i];
}
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    LL xx;
    for(int i=1;i<=n;i++){
        scanf("%lld",&xx);
        pre[i]=pre[i-1]+xx;
    }
    int opt,x,y;
    int st=0;
    int tot=0;
    LL  v;
    for(int i=1;i<=m;i++){
        scanf("%d",&opt);
        if(opt==1){
            scanf("%d%d%lld",&x,&y,&v);
            q[++tot].x=x-1;q[tot].v=v;q[tot].type=1;
            q[++tot].x=y;q[tot].v=-v;q[tot].type=1;
        }
        else{
            scanf("%d%d",&x,&y);
            ++st;
            ans[st]=pre[y]-pre[x-1];
            q[++tot].x=x-1;q[tot].v=-1;q[tot].type=2;q[tot].st=st;
            q[++tot].x=y;q[tot].v=1;q[tot].type=2;q[tot].st=st;
        }
    }
    cdq(1,tot);
    for(int i=1;i<=st;i++) printf("%lld\n",ans[i]);
}

 

posted @ 2019-03-01 12:04  我要见血小板  阅读(150)  评论(0编辑  收藏  举报