• LG P5445 [APIO2019]路灯


    Description

    一辆自动驾驶的出租车正在 Innopolis 的街道上行驶。该街道上有 $n+1$ 个停车站点,它们将街道划分成了 $n$ 条路段。每一路段都拥有一个路灯。当第 $i$ 个路灯亮起,它将照亮连接第 $i$ 与第 $i+1$ 个站点的路段。否则这条路段将是黑暗的。

    安全起见,出租车只能在被照亮的路段上行驶。换言之,出租车能从站点 $a$ 出发到达站点 $b(a < b)$ 的条件是:连接站点 $a$ 与 $a+1,a+2 cdots b-1$ 与 $b$ 的路段都被照亮。

    在经过一些意外故障或修理之后,街道上的路灯可能是亮起的,也可能是熄灭的。

    现在给定 $0$ 时刻时,街道上路灯的初始状态。之后 $1,2,ldots,q$ 时刻,每时刻会发生下列两种事件之一:

    toggle i:切换第 $i$ 个路灯的状态。具体地说,若路灯原来亮起,则现在将熄灭;若路灯原来熄灭,则现在将亮起。

    query a b:出租车部门的负责人想知道,从 $a$ 时刻起到当前时刻,有多少个时刻满足:出租车能够从站点 $a$ 出发到达站点 $b$。

    请你帮助出租车部门的负责人回答他们的问题。

    Solution

    点亮一个路灯即为连接两个明亮的路段,维护所有明亮的路段可以使用set

    维护答案时,若连接$(l_1,r_1)$和$(l_2,r_2)$,那么对于区间$[l_1cdots l_2,r_1cdots r_2]$,区间由暗变亮了,相当于矩形区间加$q-t$,$t$为此时时间

    熄灭路灯同理,求答案时相当于单点求值,若此时整个区间仍然明亮,答案需要减去$q-t$

    #include<iostream>
    #include<cstdio>
    #include<set>
    using namespace std;
    int n,q,rt[300005],cnt;
    char str[300005],opt[10];
    struct Node{
        int l,r;
        bool operator <(const Node &z)const{return r<z.r;}
    };
    struct SGT{
        int lc,rc,val;
    }tr[30000005];
    set<Node>s;
    inline int read(){
        int f=1,w=0;
        char ch=0;
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')w=(w<<1)+(w<<3)+ch-'0',ch=getchar();
        return f*w;
    }
    void update(int &i,int l,int r,int p,int v){
        if(!i)i=++cnt;
        tr[i].val+=v;
        if(l==r)return;
        int mid=l+r>>1;
        if(p<=mid)update(tr[i].lc,l,mid,p,v);
        else update(tr[i].rc,mid+1,r,p,v);
    }
    int query(int i,int l,int r,int L,int R){
        if(!i)return 0;
        if(L<=l&&r<=R)return tr[i].val;
        int mid=l+r>>1,ret=0;
        if(L<=mid)ret+=query(tr[i].lc,l,mid,L,R);
        if(R>mid)ret+=query(tr[i].rc,mid+1,r,L,R);
        return ret;
    }
    void add(int pos,int y,int v){while(pos<=n+2)update(rt[pos],1,n+2,y,v),pos+=pos&-pos;}
    void solve(int x1,int y1,int x2,int y2,int v){add(x1,y1,v),add(x2+1,y2+1,v),add(x1,y2+1,-v),add(x2+1,y1,-v);}
    int ask(int x,int y){
        int ret=0;
        while(x)ret+=query(rt[x],1,n+2,1,y),x-=x&-x;
        return ret;
    }
    int main(){
        n=read(),q=read(),scanf("%s",str+1);
        for(int i=1;i<=n+1;i++)s.insert((Node){i,i});
        for(int i=1;i<=n;i++)if(str[i]=='1'){
            set<Node>::iterator it=s.lower_bound((Node){0,i});
            int l=(*it).l;
            s.erase(it),s.erase((Node){i+1,i+1}),s.insert((Node){l,i+1});
        }
        for(set<Node>::iterator it=s.begin();it!=s.end();it++)solve((*it).l,(*it).l,(*it).r,(*it).r,q);
        for(int i=1;i<=q;i++){
            scanf("%s",opt);
            if(opt[0]=='t'){
                int x=read();
                if(str[x]=='1'){
                    set<Node>::iterator it=s.lower_bound((Node){0,x});
                    int l1=(*it).l,r1=x,l2=x+1,r2=(*it).r;
                    solve(l1,l2,r1,r2,i-q),s.erase(it),s.insert((Node){l1,r1}),s.insert((Node){l2,r2}),str[x]='0';
                }
                else{
                    set<Node>::iterator it=s.lower_bound((Node){0,x});
                    int l1=(*it).l,r1=x,l2=x+1,r2=0;
                    ++it,l2=x+1,r2=(*it).r,solve(l1,l2,r1,r2,q-i),s.erase(it),s.erase((Node){l1,r1}),s.insert((Node){l1,r2}),str[x]='1';
                }
            }
            else{
                int x=read(),y=read(),ans=ask(x,y);
                set<Node>::iterator it1=s.lower_bound((Node){0,x}),it2=s.lower_bound((Node){0,y});
                printf("%d
    ",ans-(q-i)*((*it1).l==(*it2).l));
            }
        }
        return 0;
    }
    路灯
  • 相关阅读:
    你看那个人他像一条狗
    jvm系列(八):jvm知识点总览
    jvm系列(七):jvm调优-工具篇
    百亿互金平台救火故事
    一个脚本引发的血案
    一次dns缓存引发的惨案
    一次生产事故的优化经历
    从零到百亿互联网金融架构发展史
    2016颠倒梦想,2017静心前行
    Spring Boot(九):定时任务
  • 原文地址:https://www.cnblogs.com/JDFZ-ZZ/p/14373460.html
Copyright © 2020-2023  润新知