题目描述
恭喜你找到了本场比赛的签到题!
为了让大家都有抽奖的机会,只需要复制粘贴以下代码(并且稍微填下空)即可 AC:
(我超良心的)
#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;
inline int calc(){
// 返回 set 中所有线段的并长度。(每个 pair 表示一个线段[first,second]
}
int main(){
scanf("%d%d",&N,&maxL);
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));
}
if(opt == 2){
if(L.find(MP(x,y)) == L.end()) continue;
L.erase(MP(x,y));
}
if(opt == 3){
printf("%d\n",calc());
}
}
return 0;
}输入描述:
第一行两个整数 N,L,意义如代码所述。
接下来 N 行,每行三个整数 opt,l,r,意义如代码所述。
输出描述:
对于每一组 opt=3 的询问输出一个答案。
题解
这里我们考虑用线段树的做,我们用a[N]表示节点表示的线段的覆盖次数( 不是和),b[N]表示节点表示的线段的答案,在添加时只需要将该线段在线段树中表示的线段标记加1,在删除的时候只需要将该线段在线段数中表示的线段标记减1,这样,如果要删去的线段为某一线段的子线段,那么删除后肯定能保证原线段在线段树中对应的线段标记至少为1,应为删除的线段在之前肯定添加过,这样就能保证答案的正确性。
附代码:
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
const int N = 1e7+5;
int a[N<<2],b[N<<2];
set<pii>s;
void updata(int x,int y,int z,int l,int r,int rat){
if(x<=l&&r<=y){
a[rat]+=z;
if(a[rat])b[rat]=r-l+1;
else if(l!=r)b[rat]=b[rat<<1]+b[rat<<1|1];
else b[rat]=0;//单点情况
return ;
}
int mid=(r+l)>>1;
if(mid>=x)
updata(x,y,z,l,mid,rat<<1);
if(mid<y)
updata(x,y,z,mid+1,r,rat<<1|1);
if(a[rat])b[rat]=r-l+1;
else if(l!=r)b[rat]=b[rat<<1]+b[rat<<1|1];
else b[rat]=0;//单点情况
}
int main(){
int n,m;
cin>>n>>m;
while(n--){
int opt,x,y;
cin>>opt>>x>>y;
if(opt == 1){
if(s.find((pii){x,y}) != s.end()) continue;
s.insert((pii){x,y});
updata(x,y,1,1,m,1);
}
if(opt == 2){
if(s.find((pii){x,y}) == s.end()) continue;
s.erase((pii){x,y});
updata(x,y,-1,1,m,1);
}
if(opt == 3){
cout<<b[1]<<'\n';
}
}
return 0;
}



京公网安备 11010502036488号