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;
    }
    

      

  • 相关阅读:
    linux基础
    sublime、Typora
    Windows cmd命令
    idea打包java可执行jar包
    idea常用快捷键
    Linux入门学习笔记1:VI常用命令
    442. Find All Duplicates in an Array
    566. Reshape the Matrix
    766. Toeplitz Matrix
    561. Array Partition I
  • 原文地址:https://www.cnblogs.com/SDUTNING/p/10280387.html
Copyright © 2011-2022 走看看