ACdream - 1157 Segments

题目:

由3钟类型操作:
1)D L R(1 <= L <= R <= 1000000000) 增加一条线段[L,R]
2)C i (1-base) 删除第i条增加的线段,保证每条插入线段最多插入一次,且这次删除操作一定合法
3) Q L R(1 <= L <= R <= 1000000000) 查询目前存在的线段中有多少条线段完全包含[L,R]这个线段,线段X被线段Y完全包含即LY <= LX<= RX <= RY)
给出N,接下来N行,每行是3种类型之一

思路:时间为第一位分治,然后用左区间去更新右区间

代码:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define PI acos(-1.0)
#define LL long long
#define ULL unsigned long long
#define INF 0x3f3f3f3f3f3f3f3f
#define mm(a,b) memset(a,b,sizeof(a))
#define PP puts("*********************");
template T f_abs(T a){ return a > 0 ? a : -a; }
template T gcd(T a, T b){ return b ? gcd(b, a%b) : a; }
template T lcm(T a,T b){return a/gcd(a,b)*b;}
// 0x3f3f3f3f3f3f3f3f
// 0x3f3f3f3f

const int maxn=100050;
struct Node{
    int type,x,y,id;
}q[maxn];
struct BIT{
    int n,b[2*maxn];
    void init(int _n){
        n=_n;
    }
    void add(int i,int val){
        for(;i<=n;i+=i&(-i))
            b[i]+=val;
    }
    int sum(int i){
        int ret=0;
        for(;i>0;i-=i&(-i))
            ret+=b[i];
        return ret;
    }
}bit;
int ans[maxn],vis[maxn];
int x[2*maxn],siz;
bool cmp1(const Node &a,const Node &b){
    return a.idb.y;
    return a.id=R) return;
    int mid=(L+R)>>1;
    cdq(L,mid);
    cdq(mid+1,R);
    sort(q+L,q+R+1,cmp2);
    for(int i=L;i<=R;i++){
        if(q[i].id<=mid){
            if(q[i].type==1) bit.add(q[i].y,1);
            else if(q[i].type==2) bit.add(q[i].y,-1);
        }
        else{
            if(q[i].type==3)
                ans[q[i].id]+=bit.sum(siz)-bit.sum(q[i].y-1);
        }
    }
    for(int i=L;i<=R;i++){
        if(q[i].id<=mid){
            if(q[i].type==1) bit.add(q[i].y,-1);
            else if(q[i].type==2) bit.add(q[i].y,1);
        }
    }

}
int L[maxn],R[maxn],tot;
int main(){

//    freopen("D:\\input.txt","r",stdin);
//    freopen("D:\\output.txt","w",stdout);
    int n,pos;
    char str[10];
    while(~scanf("%d",&n)){
        tot=siz=0;
        mm(vis,0);
        mm(ans,0);
        for(int i=1;i<=n;i++){
            scanf("%s",str);
            if(str[0]=='D'){
                tot++;
                scanf("%d%d",&L[tot],&R[tot]);
                x[++siz]=L[tot];
                x[++siz]=R[tot];
                q[i].type=1;
                q[i].x=L[tot];
                q[i].y=R[tot];
                q[i].id=i;
            }
            else if(str[0]=='C'){
                scanf("%d",&pos);
                q[i].type=2;
                q[i].x=L[pos];
                q[i].y=R[pos];
                q[i].id=i;
            }
            else{
                vis[i]=1;
                scanf("%d%d",&q[i].x,&q[i].y);
                q[i].type=3;
                q[i].id=i;
                x[++siz]=q[i].x;
                x[++siz]=q[i].y;
            }
        }
        sort(x+1,x+siz+1);
        siz=unique(x+1,x+siz+1)-x-1;
        for(int i=1;i<=n;i++){
            q[i].x=lower_bound(x+1,x+siz+1,q[i].x)-x;
            q[i].y=lower_bound(x+1,x+siz+1,q[i].y)-x;
        }
        bit.init(siz);
        cdq(1,n);
        for(int i=1;i<=n;i++)
            if(vis[i])
                printf("%d\n",ans[i]);
    }
    return 0;
}


你可能感兴趣的:(CDQ分治)