2018SEERC Points and Rectangles (CDQ分治)

题:http://codeforces.com/gym/101964/problem/K

分析:https://blog.csdn.net/qq_43202683/article/details/98115901

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
inline int read(){
    int sum=0,x=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')
            x=0;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
        sum=(sum<<1)+(sum<<3)+(ch^48),ch=getchar();
    return x?sum:-sum;
}
inline void write(ll x){
    if(x<0)
        putchar('-'),x=-x;
    if(x>9)
        write(x/10);
    putchar(x%10+'0');
}
#define pb push_back
#define lowbit(x) (x&(-x))
const int M=5e5+5;
int ans[M];
int tree[M];
void add(int i,int x){
    while(i<M)
        tree[i]+=x,i+=(i&(-i));
    return ;
}
int query(int i){
    int res=0;
    while(i){
        res+=tree[i];
        i-=(i&(-i));
    }
    return res;
}
struct node{
    int x,y,op,id;
    bool operator <(const node &b)const{
        return id<b.id;
    }
}a[M],temp[M];
vector<pair<int, int> > book;
void cdq1(int l, int r)//算点对矩阵的贡献(小于等于)
{
    if(r-l<=1) return;
    int midd = (r+l)>>1;
    cdq1(l, midd); 
    cdq1(midd, r);
    int i= l,j= midd,n = 0;
    while(i< midd &&j< r){
        if(a[i].x <= a[j].x){
            if(a[i].op == 1){
                add(a[i].y, 1);
                book.push_back(make_pair(a[i].y, 1));
            }
            temp[n++] = a[i++];
        }
        else{
            if(a[j].op==2){
                ans[a[j].id]+=query(a[j].y);
            }
            else if(a[j].op==3) 
                ans[a[j].id]-=query(a[j].y);
            temp[n++]=a[j++];
        }
    }
    while(i<midd) 
        temp[n++] = a[i++];
    while(j<r){
        if(a[j].op == 2)
             ans[a[j].id] += query(a[j].y);
        else if(a[j].op == 3) 
            ans[a[j].id] -= query(a[j].y);
        temp[n++]=a[j++];
    }
    for(i =l;i<r;++i) 
        a[i]=temp[i - l];
    for(i = 0; i <book.size(); ++i) 
        add(book[i].first, -book[i].second);
    book.clear(); 
    return;
}
void cdq2(int l,int r)
{
    if(r-l<= 1) 
        return;
    int midd=(l+r)>>1;
    cdq2(l,midd); 
    cdq2(midd,r);
    int i= l,j=midd,n=0;
    while(i<midd&&j<r){
        if(a[i].x<a[j].x){
            if(a[i].op == 2){
                add(a[i].y,1); 
                book.pb(make_pair(a[i].y, 1));
            }
            else if(a[i].op==3){
                add(a[i].y,-1);
                book.pb(make_pair(a[i].y,-1));
            }
            temp[n++]=a[i++];
        }
        else{
            if(a[j].op == 1){
                ans[a[j].id] +=query(a[j].y-1);
            }
            temp[n++]=a[j++];
        }
    }
    while(i<midd)
        temp[n++]=a[i++];//temp[o++] = e[lp++]?? = temp[lp++],debug???
    while(j<r){
        if(a[j].op == 1) {
            ans[a[j].id] +=query(a[j].y - 1);
        }
        temp[n++]=a[j++];
    }
    for(i=l;i<r;i++) 
        a[i]=temp[i-l];
    for(i=0;i<book.size();i++) 
        add(book[i].first,-book[i].second);
    book.clear(); 
    return;
}
int lisan[M<<2];
int main(){
    int n=read();
    int tot=0,num=0;
    for(int i=0;i<n;i++){
        int op=read();
        if(op==1){
            a[tot].x=read(),a[tot].y=read();
            a[tot].op=1,a[tot].id=i;
            lisan[++num]=a[tot].x,lisan[++num]=a[tot].y;
            tot++;
        }
        else{
            int x1=read(),y1=read(),x2=read(),y2=read();
            a[tot].op=2,a[tot].x=x1-1,a[tot].y=y1-1,a[tot].id=i,tot++;
            a[tot].op=2,a[tot].x=x2,a[tot].y=y2,a[tot].id=i,tot++;
            a[tot].op=3,a[tot].x=x1-1,a[tot].y=y2,a[tot].id=i,tot++;
            a[tot].op=3,a[tot].x=x2,a[tot].y=y1-1,a[tot].id=i,tot++;
            lisan[++num]=x1-1,lisan[++num]=x2,lisan[++num]=y1-1,lisan[++num]=y2;    
        }
        
        
    }
    sort(lisan+1,lisan+num+1);
    int m=unique(lisan+1,lisan+1+num)-lisan-1;
    for(int i=0;i<tot;i++){
        a[i].x=lower_bound(lisan+1,lisan+1+m,a[i].x)-lisan;
        a[i].y=lower_bound(lisan+1,lisan+1+m,a[i].y)-lisan;
//        cout<<a[i].x<<"~~~~"<<a[i].y<<endl;
    }
    cdq1(0,tot);
    
    sort(a,a+tot);
    cdq2(0,tot);
    ll ANS=0ll;
    for(int i=0;i<n;i++){
        ANS+=ans[i];
        write(ANS);
        puts("");
    }
    return 0;    
}
View Code
原文地址:https://www.cnblogs.com/starve/p/11627088.html