JZOJ5821手机信号

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

JZOJ5821手机信号

上一篇:application.yml使用@符合问题:'@' that cannot start any token. (Do not use @ for indentation)


下一篇:动画效果----webkit-animation