• bzoj5007: TCP协议


    Description

    在如今的网络中,TCP是一种被广泛使用的网络协议,它在传输层提供了可靠的通信服务。众所周知,网络是存在
    时延的,例如用户先后向服务器发送了两个指令op1和op2,并且希望服务器先处理指令op1,再处理指令op2;但由
    于网络时延,这两个指令可能会失序到达,而导致服务器先执行了指令op2,这是我们不希望看到的。TCP协议拥有
    将失序到达的报文按顺序重组的功能,一种方法是给每一个报文打上一个时间戳。而你今天要实现的功能比这个要
    简单很多。我们需要你维护一个服务器,这个服务器的功能是一个简单的栈,你会接收三种用户的指令:
    push x t --- 表示将x元素入栈,这条指令的时间戳为t
    pop t --- 表示将栈顶元素弹出,这条指令的时间戳为t
    peak t --- 用户询问现在栈顶元素的值,这条指令的时间戳为t
    当一条时间戳为t的指令到达时,你需要进行如下处理:
    1.将所有之前执行的时间戳大于t的push和pop指令全部撤销
    2.执行当前这条指令
    3.按时间戳顺序重新执行在第1步被撤销的指令
    注意你不需要撤销以及重新执行之前已经执行过的peak指令
    也就是说每一条peak指令只有在它到达的时候会被执行一次。
    我们保证每一条指令的时间戳都是唯一的;
    若你在需要执行一条pop指令时发现当前栈为空,则当前你可以忽略这条指令。

    Input

    第一行包含一个整数n,表示指令总数。
    接下来n行按指令到达服务器的顺序给出每一条指令,有三种类型
    push x t
    pop t
    peak t
    1 <= n <= 300000,0 <= x,t <= 1000000000

    Output

    对于每一条peak指令,输出对应的答案占一行;若栈为空,输出-1。
    用线段树维护操作对应的括号序列的前缀和(push=1,pop=-1,peak=0,未执行=0),查询相当于查询一个位置向左第一个小于指定值的位置。
    #include<bits/stdc++.h>
    const int N=300007;
    char buf[N*35],*ptr=buf;
    int _(){
        int x=0;
        while(*ptr<48)++ptr;
        while(*ptr>47)x=x*10+*ptr++-48;
        return x;
    }
    int n,ts[N],qs[N][3],tp=0,vs[N];
    int _x,_a,_p;
    int min(int a,int b){return a<b?a:b;}
    struct node{
        node*lc,*rc;
        int L,R,M;
        int mn,a;
        void add(int x){
            mn+=x,a+=x;
        }
        void dn(){
            if(a){
                lc->add(a);
                rc->add(a);
                a=0;
            }
        }
        void up(){
            mn=min(lc->mn,rc->mn);
        }
        void add(){
            if(_x<=L)return add(_a);
            dn();
            if(_x<=M)lc->add();
            rc->add();
            up();
        }
        int at(){
            if(L==R)return mn;
            dn();
            return (_x<=M?lc:rc)->at();
        }
        bool find(){
            if(mn>=_a)return 0;
            if(L==R)return _p=R+1,1;
            dn();
            if(_x>M&&rc->find())return 1;
            return lc->find();
        }
    }ns[N*2],*np=ns,*rt;
    node*build(int L,int R){
        node*w=np++;
        w->L=L,w->R=R;
        if(L<R){
            int M=w->M=L+R>>1;
            w->lc=build(L,M);
            w->rc=build(M+1,R);
        }
        return w;
    }
    int $(int x){
        return std::lower_bound(ts,ts+tp,x)-ts;
    }
    int main(){
        fread(buf,1,sizeof(buf),stdin);
        n=_();
        ts[tp++]=-10;
        for(int i=1;i<=n;++i){
            qs[i][0]=_();
            qs[i][1]=_();
            if(qs[i][0]==71626)ts[tp++]=qs[i][2]=_();
            else ts[tp++]=qs[i][1];
        }
        std::sort(ts,ts+tp);
        rt=build(0,tp-1);
        vs[0]=-1;
        for(int i=1;i<=n;++i){
            if(qs[i][0]==71626){
                _x=$(qs[i][2]);
                vs[_x]=qs[i][1];
                _a=1,rt->add();
            }else if(qs[i][0]==7094){
                _x=$(qs[i][1]);
                _a=-1,rt->add();
            }else{
                _x=$(qs[i][1]);
                _a=rt->at();
                _p=0;
                rt->find();
                printf("%d
    ",vs[_p]);
            }
        }
        return 0;
    }
  • 相关阅读:
    API接口智能化测试探索与实践
    程序员的社会地位
    程序员五六年能存100万,你说你焦虑个啥!!!
    苹果公司宣布:公司内部的员工有权讨论自己的工作条件和薪酬
    男子股票账户突然多了一个亿!结果……
    你选择双休还是单休?
    PAL制式和NTSC制式的定义及区别(转)
    javascript入门系列演示·三种弹出对话框的用法实例(转)
    sink相关
    Ubuntu下安装gsteditor
  • 原文地址:https://www.cnblogs.com/ccz181078/p/7501584.html
Copyright © 2020-2023  润新知