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