zoukankan      html  css  js  c++  java
  • BZOJ-10-1176: [Balkan2007]Mokia-CDQ第二类应用

    思路 :按照操作的时间进行分治,这样转化成了 时间t ,x坐标,y坐标 经典的三维偏序。

    最初时间就是递增顺序,无需排序直接进行第二维的分治,类似归并排序处理x坐标,在保证

    x有序的情况下进行更新y坐标的树状数组。求一个  (x1,y1)   - (x2,y2)矩形内点的个数,简单容斥一下

    求[ (1,1) ——(x1-1,y1-1) ]+[ (1,1) ——(x2,y2) ]-[ (1,1) ——(x1-1,y1) ]-[ (1,1) ——(x1,y1-1) ]   

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define maxn 2234567
    ll op,w,s,x[3],y[3];
    ll cnt,q[maxn],tot;
    ll ans[maxn],tree[maxn];
    struct node
    {
        int x,y,id,ad;
    } data[maxn],cp[maxn];
    int lowbit(int x)
    {
        return x&-x;
    }
    void add(int x,int d)
    {
        while(x<=w)
        {
            tree[x]+=d;
            x+=lowbit(x);
        }
    }
    ll query(int x)
    {
        ll re=0;
        while(x>0)
        {
            re+=tree[x];
            x-=lowbit(x);
        }
        return re;
    }
    void cdq(int l,int r)
    {
        if(l>=r)return ;
        int mid=(l+r)/2;
        cdq(l,mid);
        cdq(mid+1,r);
        int t1=l,t2=mid+1,ct=l;
        while(t2<=r)
        {
            while(data[t1].x<=data[t2].x&&t1<=mid)
            {
                if(data[t1].id==0)
                    add(data[t1].y,data[t1].ad);
                cp[ct++]=data[t1++];
            }
            if(data[t2].id!=0)ans[data[t2].ad]+=query(data[t2].y);
            cp[ct++]=data[t2++];
        }
        for(int i=l; i<t1; i++)
            if(data[i].id==0)
                add(data[i].y,-data[i].ad);
        while(t1<=mid)cp[ct++]=data[t1++];
        while(t2<=r)cp[ct++]=data[t2++];
        for(int i=l; i<=r; i++)
            data[i]=cp[i];
    }
    int main()
    {
        scanf("%lld%lld",&s,&w);
        while(1)
        {
            scanf("%lld",&op);
            if(op==1)
            {
                data[++cnt].id=0;
                scanf("%lld%lld%lld",&data[cnt].x,&data[cnt].y,&data[cnt].ad);
            }
            else if(op==2)
            {
                scanf("%lld%lld%lld%lld",&x[1],&y[1],&x[2],&y[2]);
                q[++tot]=cnt+1;
                ans[cnt+4]+=(y[2]-y[1]+1)*(x[2]-x[1]+1)*s;
                data[++cnt].x=x[1]-1,data[cnt].y=y[1]-1,data[cnt].id=2,data[cnt].ad=cnt;
                data[++cnt].x=x[1]-1,data[cnt].y=y[2],data[cnt].id=2,data[cnt].ad=cnt;
                data[++cnt].x=x[2],data[cnt].y=y[1]-1,data[cnt].id=2,data[cnt].ad=cnt;
                data[++cnt].x=x[2],data[cnt].y=y[2],data[cnt].id=3,data[cnt].ad=cnt;
            }
            else break;
        }
        cdq(1,cnt);
        for(int i=1; i<=tot; i++)
            printf("%lld
    ",ans[q[i]+3]-ans[q[i]+1]-ans[q[i]+2]+ans[q[i]]);
        return 0;
    }
    

      

  • 相关阅读:
    LeetCode 382. Linked List Random Node
    LeetCode 398. Random Pick Index
    LeetCode 1002. Find Common Characters
    LeetCode 498. Diagonal Traverse
    LeetCode 825. Friends Of Appropriate Ages
    LeetCode 824. Goat Latin
    LeetCode 896. Monotonic Array
    LeetCode 987. Vertical Order Traversal of a Binary Tree
    LeetCode 689. Maximum Sum of 3 Non-Overlapping Subarrays
    LeetCode 636. Exclusive Time of Functions
  • 原文地址:https://www.cnblogs.com/SDUTNING/p/10280387.html
Copyright © 2011-2022 走看看