description:

n条线段 需要设计一个数据结构提供插入和删除 和查询并集的长度

solution:

所给代码里用set 里套了个pair 来实现插入和删除 查询操作采用线段树维护每个线段的长度 可以实现log更新 O1得到答案

code:

#include <algorithm>
 #include <iostream>
 #include <cstring>
 #include <climits>
 #include <cstdio>
 #include <vector>
 #include <cstdlib>
 #include <ctime>
 #include <cmath>
 #include <queue>
 #include <stack>
 #include <map>
 #include <set>
 #define fi first
 #define lc (x<<1)
 #define se second
 #define U unsigned
 #define rc (x<<1|1)
 #define Re register
 #define LL long long
 #define MP std::make_pair
 #define CLR(i,a) memset(i,a,sizeof(i))
 #define FOR(i,a,b) for(Re int i = a;i <= b;++i)
 #define ROF(i,a,b) for(Re int i = a;i >= b;--i)
 #define SFOR(i,a,b,c) for(Re int i = a;i <= b;i+=c)
 #define SROF(i,a,b,c) for(Re int i = a;i >= b;i-=c)
 #define DEBUG(x) std::cerr << #x << '=' << x << std::endl
 const int MAXN = 1000000+5;
 int N,maxL;
 std::set<std::pair<int,int> > L;

int t[MAXN << 2],s[MAXN << 2];

void pushup(int v){
    s[v] = s[v << 1] + s[v << 1 | 1];
}

 void update(int v,int L,int R,int l,int r,int val){
     if(L <= l && r <= R){
         t[v] += val;
         if(t[v]){
             s[v] = r - l +1;
         }else if(l != r){
             pushup(v);
         }
        return ;
     }

     int mid = l + r >> 1;

     if(L <= mid){
         update(v << 1,L,R,l,mid,val);
     }

     if(mid < R){
         update(v << 1 | 1,L,R,mid + 1,r,val);
     }

     if(t[v]){
         s[v] = r - l + 1;
     }else{
         pushup(v);
     }
 }

 int main(){
     scanf("%d%d",&N,&maxL);
     int res = 0;

     while(N--){
         int opt,x,y;
         scanf("%d%d%d",&opt,&x,&y);
         if(opt == 1){
             if(L.find(MP(x,y)) != L.end()) continue;
             L.insert(MP(x,y));
             update(1,x,y,1,maxL,1);
         }
         if(opt == 2){
             if(L.find(MP(x,y)) == L.end()) continue;
             L.erase(MP(x,y));
             update(1,x,y,1,maxL,-1);
         }
         if(opt == 3){
             printf("%d\n",s[1]);
         }
     }
     return 0;
 }