zoukankan      html  css  js  c++  java
  • Luogu P4390 [BOI2007]Mokia 摩基亚 | CDQ分治

    题目链接

    $CDQ$分治。

    考虑此时在区间$[l,r]$中,要计算$[l,mid]$中的操作对$[mid+1,r]$中的询问的影响。

    计算时,排序加上树状数组即可。

    然后再递归处理$[l,mid]$和$[mid+1,r]$。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
        using namespace std;
        const int MAX=2000005;
    struct data
    {
        int opt,x,y,y1,w,num;
        data(int a=0,int b=0,int c=0,int d=0,int e=0,int f=0)
            {opt=a,x=b,y=c,y1=d,w=e,num=f;}
    }s[200005],g[200005];
    bool cmp(data u,data v)
        {return (u.x==v.x)?(u.opt<v.opt):(u.x<v.x);}
        int ans[10005],val[2000100];
    int lowbit(int x) {return x&(-x);}
    void add(int x,int y) {for(;x<=MAX;x+=lowbit(x)) val[x]+=y;}
    int  ask(int x)       {int ans=0;for(;x;x-=lowbit(x))ans+=val[x];return ans;}
    void cln(int x)       {for(;x<=MAX;x+=lowbit(x)) val[x]=0;}
    int  Get(int l,int r) {return ask(r)-ask(l-1);}
    void Sol(int l,int mid,int r)
    {
        int k=0;
        for(int i=l;i<=mid;i++)
            if(s[i].opt==1) g[++k]=s[i];
        for(int i=mid+1;i<=r;i++)
            if(s[i].opt!=1) g[++k]=s[i];
        sort(g+1,g+k+1,cmp);
        for(int i=1;i<=k;i++)
        {
            if(g[i].opt==1) add(g[i].y,g[i].w);
            if(g[i].opt==2) ans[g[i].num]-=Get(g[i].y,g[i].y1);
            if(g[i].opt==3) ans[g[i].num]+=Get(g[i].y,g[i].y1);
        }
        for(int i=1;i<=k;i++)
            if(g[i].opt==1) cln(g[i].y);
    }
    void CDQ(int l,int r)
    {
        if(l==r) return;
        int mid=(l+r)>>1;
        CDQ(l,mid),CDQ(mid+1,r);
        Sol(l,mid,r);
    }
    int main()
    {
        int n=0,cnt=0,tot=0;
        scanf("%d%d",&n,&n);
        for(;;)
        {
            int opt=0;
            scanf("%d",&opt);
            if(opt==3) break;
            if(opt==1)
            {
                s[++cnt].opt=1;
                scanf("%d%d%d",&s[cnt].x,&s[cnt].y,&s[cnt].w);
                s[cnt].x++,s[cnt].y++;
            }
            if(opt==2)
            {
                tot++;
                s[++cnt].opt=2,s[cnt].num=tot;
                scanf("%d%d",&s[cnt].x,&s[cnt].y),s[cnt].y++;
                s[++cnt].opt=3,s[cnt].num=tot;
                scanf("%d%d",&s[cnt].x,&s[cnt].y1),s[cnt].x++,s[cnt].y1++;
                s[cnt].y=s[cnt-1].y;
                s[cnt-1].y1=s[cnt].y1;
            }
        }
        CDQ(1,cnt);
        for(int i=1;i<=tot;i++) printf("%d
    ",ans[i]);
        return 0;
    }
    Luogu P4390
  • 相关阅读:
    Unique Binary Search Trees 解答
    Unique Paths II 解答
    Unique Paths 解答
    Maximum Subarray 解答
    Climbing Stairs 解答
    House Robber II 解答
    House Robber 解答
    Valid Palindrome 解答
    Container With Most Water 解答
    Remove Duplicates from Sorted List II 解答
  • 原文地址:https://www.cnblogs.com/wozaixuexi/p/11246767.html
Copyright © 2011-2022 走看看