版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34454069/article/details/88787830
题目:
分析:
辣鸡51nod
前两题迅速切掉花了1h
先写了一个
的算法,T了,开始想->放弃:1h
再写了一个
的算法,又T了,开始想->放弃:2h
最后无奈又想了一个
的算法,没调完GG
最后一看 尼玛要跑400ms左右。。这 肯定过不去了。。但这特么N才1e5啊。。。
是没开O2导致set复杂度退化了吗…
题解给的方法和我最后想的方法差不多。。只不过他是用的set,我是想用线段树的懒标记维护
很显然,每种笑话是独立的,因此只需要考虑某种笑话的影响区间即可
所以,每次拿到一个新的区间,先把他覆盖的范围全部改为1,再和它原来同种笑话的区间求交,交的部分全部改为0。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<set>
#define SF scanf
#define PF printf
#define MAXN 100010
using namespace std;
typedef pair<int,int> pii;
typedef set<pii>::iterator sit;
set<pii>col[MAXN];
int n,m;
int sum[MAXN*4],tag[MAXN*4];
void pushdown(int x,int l,int r){
int mid=(l+r)>>1;
if(tag[x]){
tag[x<<1]=tag[x<<1|1]=tag[x];
if(tag[x]==2){
sum[x<<1]=mid-l+1;
sum[x<<1|1]=r-mid;
}
else
sum[x<<1]=sum[x<<1|1]=0;
tag[x]=0;
}
}
void pushup(int x){
sum[x]=sum[x<<1]+sum[x<<1|1];
}
void change(int id,int l,int r,int pl,int pr,int val){
// PF("[%d %d %d]\n",pl,pr,val);
if(l!=r)
pushdown(id,l,r);
if(pl<=l&&pr>=r){
tag[id]=val+1;
if(val==0)
sum[id]=0;
else
sum[id]=r-l+1;
return ;
}
int mid=(l+r)>>1;
if(pl<=mid)
change(id<<1,l,mid,pl,pr,val);
if(pr>mid)
change(id<<1|1,mid+1,r,pl,pr,val);
pushup(id);
}
void add(int l,int r,int id){
pii x=make_pair(l,l);
sit itx=col[id].lower_bound(x);
sit lft=itx,rit=itx;
int pl=l,pr=r;
bool flag=0;
change(1,1,n,l,r,1);
for(sit it=itx;itx!=col[id].begin();){
it--;
if(it->second<l)
break;
lft=it;
change(1,1,n,max(l,it->first),min(r,it->second),0);
pl=min(pl,it->first);
itx=it;
}
for(sit it=itx;it!=col[id].end()&&it->first<=r;){
change(1,1,n,max(l,it->first),min(r,it->second),0);
pr=max(pr,it->second);
it++;
rit=it;
// col[id].erase(it++);
}
for(sit it=lft;it!=rit;)
col[id].erase(it++);
col[id].insert(make_pair(pl,pr));
}
int query(int id,int l,int r,int pl,int pr){
if(l!=r)
pushdown(id,l,r);
if(pl<=l&&pr>=r)
return sum[id];
int mid=(l+r)>>1;
int res=0;
if(pl<=mid)
res+=query(id<<1,l,mid,pl,pr);
if(pr>mid)
res+=query(id<<1|1,mid+1,r,pl,pr);
pushup(id);
return res;
}
int main(){
SF("%d%d",&n,&m);
int opt,x,num,k,l,r;
for(int i=1;i<=m;i++){
SF("%d",&opt);
if(opt==1){
SF("%d%d%d",&x,&num,&k);
l=x-k,r=x+k;
add(l,r,num);
}
else{
SF("%d%d",&l,&r);
PF("%d\n",query(1,1,n,l,r));
}
}
}