JZOJ5821手机信号

用set维护,(l,r,v),注意边界,保证了两个端点l,r一定有信号站

增加有三种可能,1.直接加(没有影响),2.将原本的一个区间变成两个 3.将原本的一个区间变成三个

删除有三种情况,1.全包含直接删 2.部分删除 ,要增加一个 3.部分删除要增加两个

code:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cctype>
#include<set>
#include<cmath>
using namespace std;
const int MAXX=200010;
const long long inff=2000000000000000000ll;
struct node
{
	node(){}
	node(long long a,long long b,long long c){l=a;r=b;v=c;}
	long long l,r,v;
	bool operator <(const node &a)const {
            return l<a.l;
	}
};
set<node>s;
int n;
long long w;
inline long long rd(){
	long long x=0;bool f=0;
	char c=getchar();
	while(!isdigit(c)){
		if(c=='-')f=1;
		c=getchar();
	}
	while(isdigit(c)){
		x=(x<<1)+(x<<3)+(c^48);
		c=getchar();
	}
	return f?-x:x;
}
inline void buld(long long l,long long r,long long v){
    s.insert(node(l,r - (r - l) % v,v));
    set<node>::iterator it=s.lower_bound(node(l,r - (r - l)%v,v)),ptr;
    if(it!=s.begin()){
        ptr=--it;
        node p=*ptr;
        if(ptr -> r >= l){
        	s.erase(ptr);
            if(l-1 >= p.l)s.insert(node(p.l,l - 1 - (l - 1 - p.l) % p.v,p.v));
            if(r+1 <= p.r){
            	long long lef;
            	if((r + 1 - p.l) % p.v == 0)lef = r + 1;
            	else lef=r + 1 + p.v - (r + 1 - p.l) % p.v;
                s.insert(node(lef,p.r,p.v)); 
            }
        }
    }
}
inline void del(long long l,long long r){
	set<node>::iterator bg=s.upper_bound(node(l,r,1));
	set<node>::iterator ed=s.upper_bound(node(r,r,1));
	if(bg != s.begin())bg--;
	for(set<node>::iterator it = bg;it != ed;){
		set<node>::iterator ptr = it;
		node p=*it;
		it++;//注意要先++,因为之后会把他删掉
        if(p.r >= l){
        	s.erase(ptr);
        	if(l - 1 >= p.l)s.insert(node(p.l,l - 1 - (l - 1 -p.l) % p.v,p.v));
        	if(r + 1 <= p.r){
        		long long lef ;
        		if((r + 1 - p.l) % p.v == 0) lef = r + 1 ;
        		else lef =r + 1 + p.v - (r + 1 - p.l) % p.v;
        		s.insert(node(lef,p.r,p.v)); 
        	}
        }
	}
}
inline long long query(long long x){
	long long d;
    if(s.size()==1)return 0;
    set<node>::iterator nxt = s.lower_bound(node(x,x,1));
    set<node>::iterator las = nxt;
    if(las != s.begin())las--;
    if(las -> r >= x && las -> l <= x){
         long long lef = x - (x - las -> l) % las -> v;
         long long rig = x + las -> v - (x - las -> l) % las -> v; 
         d=min(abs(x - lef) , abs(x - rig));

    }else if(nxt -> l <= x && nxt -> r >= x){
         long long lef = x - (x - nxt -> l) % nxt -> v;
         long long rig = x + nxt -> v - (x - nxt -> l) % nxt -> v; 
         d=min(abs(x - lef) , abs(x - rig));
    }else d=min(abs(las -> r - x),abs(nxt -> l - x));
    long long  ans = w - d * d;
    return max(0ll,ans);
}
int main(){
	freopen("cellphone.in","r",stdin);
	freopen("cellphone.out","w",stdout);
	n=rd();w=rd();
	s.insert(node(inff,inff+1,1));
	for(int i=1;i<=n;++i){
		char s[20];
		long long l,r,v,x;
		scanf("%s",&s);
	    if(s[0]=='c'){
            l=rd();r=rd();v=rd();
            buld(l,r,v);
	    }else if(s[0]=='d'){
            l=rd();r=rd();
            del(l,r);
	    }else if(s[0]=='q'){
	    	x=rd();
	    	#ifndef LOCAL
	    	printf("%lld\n",query(x));
	    	#else
	    	cout<<query(x)<<endl;
	    	#endif
	    }
	}
	return 0;
}
posted @ 2018-10-12 19:16  ART_coder  阅读(171)  评论(0编辑  收藏  举报