ACdream 1157 Segments 【CDQ分治】

链接:http://acdream.info/problem?pid=1157

题意:中文题

分析:与bzoj1176分析一致,要求是这条线段被多少条包含,所以我们按x<=x1,y>=y1,z<=z排序,然后求y把树状数组改成向下更新,向上求和。

代码:

#include <algorithm>
#include <iostream>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <queue>
#include <cmath>
#include <stack>
#include <set>
#include <map>
#include <ctime>
#define INF 0x3f3f3f3f
#define Mn 200010
#define Mm 200010
#define mod 1000000007
#define CLR(a,b) memset((a),(b),sizeof((a)))
#define CPY(a,b) memcpy ((a), (b), sizeof((a)))
#pragma comment(linker, "/STACK:102400000,102400000")
#define ul (u<<1)
#define ur (u<<1)|1
using namespace std;
typedef long long ll;
struct node {
    int x,y,z,val,id;
    node(){}
    node(int x,int y,int z,int val,int id):x(x),y(y),z(z),val(val),id(id){}
    bool operator <(const node a) const {
        if(a.x!=x) return x<a.x;
        if(a.y!=y) return y>a.y;
        if(a.z!=z) return z<a.z;
    }
    void pt() {
        cout<<x<<" "<<y<<" "<<z<<" "<<val<<" "<<id<<endl;
    }
}q[Mn],tmp[Mn];
int bit[Mn];
int num;
int lowbit(int x) {return x&(-x);}
void push(int x,int val) {
    while(x>0) {
        bit[x]+=val;
        x-=lowbit(x);
    }
}
int sum(int x) {
    int re=0;
    if(!x) x++;
    while(x<=num) {
        re+=bit[x];
        x+=lowbit(x);
    }
    return re;
}
int ans[Mn];
void cdq(int l,int r) {
    if(l==r) return ;
    int mid=(l+r)>>1;
    for(int i=l;i<=r;i++) {
        if(q[i].z<=mid&&!q[i].id) push(q[i].y,q[i].val);
        else if(q[i].z>mid&&q[i].id) ans[q[i].id]+=sum(q[i].y);
    }
    for(int i=l;i<=r;i++) {
        if(q[i].z<=mid&&!q[i].id) push(q[i].y,-q[i].val);
    }
    int L=l,R=mid+1;
    for(int i=l;i<=r;i++) {
        if(q[i].z<=mid) {
            tmp[L++]=q[i];
        } else tmp[R++]=q[i];
    }
    for(int i=l;i<=r;i++) q[i]=tmp[i];
    cdq(l,mid);
    cdq(mid+1,r);
}
vector<pair<int,int> > vc;
int b[Mn];
int main() {
    int n;
    int x,y;
    char s[10];
    while(~scanf("%d",&n)) {
        int id=0;vc.clear();
		num=0;
        for(int i=1;i<=n;i++) {
            scanf("%s",s);
            if(s[0]=='D') {
                scanf("%d%d",&x,&y);
                vc.push_back(make_pair(x,y));
                b[num++]=x;
                b[num++]=y;
                q[i]=node(x,y,i,1,0);
            } else if(s[0]=='C') {
                scanf("%d",&x);
                q[i]=node(vc[x-1].first,vc[x-1].second,i,-1,0);
            } else {
                scanf("%d%d",&x,&y);
                b[num++]=x;
                b[num++]=y;
                q[i]=node(x,y,i,0,++id);
            }
        }
        sort(b,b+num);
        num=unique(b,b+num)-b;
        for(int i=1;i<=n;i++) {
            q[i].x=lower_bound(b,b+num,q[i].x)-b+1;
            q[i].y=lower_bound(b,b+num,q[i].y)-b+1;
        }
        CLR(bit,0);
        CLR(ans,0);
        sort(q+1,q+n+1);
        cdq(1,n);
        for(int i=1;i<=id;i++) {
            printf("%d\n",ans[i]);
        }
         
    }
    return 0;
}


你可能感兴趣的:(ACdream 1157 Segments 【CDQ分治】)