• [bzoj3938] [Uoj #88] Robot


    Description

    (q)(n) 只机器人,一开始他把机器人放在了一条数轴上,第 (i) 只机器人在 (a_i) 的位置上静止,而自己站在原点。在这之后小 (q) 会执行一些操作,他想要命令一个机器人向左或者向右移动 (x) 格。但是机器人似乎听不清小 (q) 的命令,事实上它们会以每秒 (x) 格的速度匀速移动。看着自己的机器人越走越远,小 (q) 很着急,他想知道当前离他(原点)最远的机器人有多远。具体的操作以及询问见输入格式。注意,不同的机器人之间互不影响,即不用考虑两个机器人撞在了一起的情况。

    Input

    共有 (m) 个事件,输入将会按事件的时间顺序给出。
    第一行两个正整数 (n),(m) 。接下来一行 (n) 个整数,第 (i) 个数是 (a_i),表示第 (i) 个机器人初始的位置(初始移动速度为0)。
    接下来 (m) 行,每行行首是一个非负整数 (t_i) ,表示该事件点发生的时刻(以秒为单位)。
    第二个是一个字符串 (S),代表操作的种类。数字与字符串之间用一个空格隔开。接下来的输入按 (S) 的种类分类。若 (S)(“command”)(不带引号),则接下来两个整数 (k_i) ,$ x_i$ ,表示小 (q) 对第 (k_i) 个机器人执行了操作,该机器人的速度将会被重置,变为向数轴正方向每秒移动 (x_i) 格(若 (x_i) 为负数就相当于向数轴负方向每秒移动 (∣x_i∣)格)。保证 (1leq k_i leq n)。若 (S)(“query”)(不带引号),则你需要输出当前离原点最远的机器人有多远。
    保证 $t1 leq t2 leq ... leq tm $。(注:若同一时间发生多次操作,则按读入顺序依次执行)

    Output

    对于每个 (query) 询问,输出一行,包含一个整数表示正确的答案。

    Sample Input

    4 5

    -20 0 20 100

    10 command 1 10

    20 command 3 -10

    30 query

    40 command 1 -30

    50 query

    Sample Output

    180

    280

    HINT

    第一个命令执行时,各个机器人的位置为:−20,0,20,100。

    第二个命令执行时,各个机器人的位置为:80,0,20,100。

    第一个询问时,各个机器人的位置为:180,0,−80,100。

    第三个命令执行时,各个机器人的位置为:280,0,−180,100。

    第二个询问时,各个机器人的位置为:−20,0,−280,100。

    限制与约定

    (command) 的个数为 (C)(query) 的个数为 (Q)。(所以 (C+Q=m)

    对于所有的事件满足 (0 leq ti leq 10^9),对于所有的 (command) 满足 (∣x_i∣ leq 10^4)

    对于所有的机器人满足 (∣a_i∣ leq 10^9)

    (N,C leq 10^5)

    (Q leq 5 imes 10^5)


    想法

    稍稍转化一下,以时间为 (x) 轴,位置为 (y) 轴,就是一道经典的李超线段树题。
    就是处理细节比较多,要离线处理插入的线段,要对时间离散化。


    代码

    明明是道水题,我却调了2个多小时,因为一些奇奇怪怪的原因(如 (double)(longlong) 啊,对时间离散化还是动态开点啊,线段的端点问题啊。。。)

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
     
    using namespace std;
     
    int read(){
        int x=0,f=1;
        char ch=getchar();
        while(!isdigit(ch) && ch!='-') ch=getchar();
        if(ch=='-') f=-1,ch=getchar();
        while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
     
    const int N = 600005;
    typedef double db;
    typedef long long ll;
     
    struct seg{
        int x0,x1;
        ll k,b;
        seg() { x0=x1=0; k=b=0.0; }
        seg(int _x0,int _x1,ll _k,ll _b) { x0=_x0; x1=_x1; k=_k; b=_b; }
    }d[N];
    int tot;
    int ask[N],num;
     
    int n;
    ll K[N],B[N];
    int st[N];
     
    int rk[N*2],rn;
    struct node{
        node *ch[2];
        int mx,mn;
        node() { mx=mn=0; ch[0]=ch[1]=NULL; }
    }pool[N*4],*root;
    int cnt;
    void build(node *p,int l,int r){
        if(l==r) return;
        int mid=(l+r)>>1;
        build(p->ch[0]=&pool[++cnt],l,mid);
        build(p->ch[1]=&pool[++cnt],mid+1,r);
    }
    inline ll cal(int x,int c) { return d[x].k*rk[c]+d[x].b; }
    bool better_mn(int x,int y,int c) { 
        if(!x) return false;
        if(!y) return true;
        return cal(x,c)<cal(y,c);
    }
    bool better_mx(int x,int y,int c) { 
        if(!x) return false;
        if(!y) return true;
        return cal(x,c)>cal(y,c);
    }
    void insert_mx(node *p,int l,int r,int L,int R,int c){
        if(l==L && r==R){
            int mid=(l+r)>>1;
            if(better_mx(c,p->mx,mid)) swap(p->mx,c);
            int tl=better_mx(p->mx,c,l),tr=better_mx(p->mx,c,r);
            if(c==0 || l==r || (tl && tr)) return;
            if(tl) insert_mx(p->ch[1],mid+1,r,mid+1,r,c);
            else insert_mx(p->ch[0],l,mid,l,mid,c);
            return;
        }
        int mid=(l+r)>>1;
        if(R<=mid) insert_mx(p->ch[0],l,mid,L,R,c);
        else if(L>mid) insert_mx(p->ch[1],mid+1,r,L,R,c);
        else{
            insert_mx(p->ch[0],l,mid,L,mid,c);
            insert_mx(p->ch[1],mid+1,r,mid+1,R,c);
        }
    } 
    void insert_mn(node *p,int l,int r,int L,int R,int c){
        if(l==L && r==R){
            int mid=(l+r)>>1;
            if(better_mn(c,p->mn,mid)) swap(p->mn,c);
            int tl=better_mn(p->mn,c,l),tr=better_mn(p->mn,c,r);
            if(c==0 || l==r || (tl && tr)) return;
            if(tl) insert_mn(p->ch[1],mid+1,r,mid+1,r,c);
            else insert_mn(p->ch[0],l,mid,l,mid,c);
            return;
        }
        int mid=(l+r)>>1;
        if(R<=mid) insert_mn(p->ch[0],l,mid,L,R,c);
        else if(L>mid) insert_mn(p->ch[1],mid+1,r,L,R,c);
        else{
            insert_mn(p->ch[0],l,mid,L,mid,c);
            insert_mn(p->ch[1],mid+1,r,mid+1,R,c);
        }
    } 
    int Mx,Mn;
    void query(node *p,int l,int r,int c){
        Mx = better_mx(p->mx,Mx,c) ? p->mx : Mx ;
        Mn = better_mn(p->mn,Mn,c) ? p->mn : Mn ;
        if(l==r) return;
        int mid=(l+r)>>1;
        if(c<=mid) query(p->ch[0],l,mid,c);
        else query(p->ch[1],mid+1,r,c);
    }
     
    int main()
    {
        int m,t,id,x;
        char s[10];
        n=read();  m=read();
        for(int i=1;i<=n;i++)
            K[i]=0,B[i]=read(),st[i]=1;
        while(m--){
            t=read()+1;
            rk[++rn]=t;
            scanf("%s",s);
            if(s[0]=='c'){
                id=read(); x=read();
                d[++tot]=seg(st[id],t,K[id],B[id]);
                st[id]=t;
                B[id]=K[id]*t+B[id]-1ll*x*t;
                K[id]=x;
            }
            else ask[num++]=t;
        }
        for(int i=1;i<=n;i++) d[++tot]=seg(st[i],t,K[i],B[i]);
        rk[++rn]=1;
         
        sort(rk+1,rk+1+rn);
        rn=unique(rk+1,rk+1+rn)-rk-1;
        build(root=&pool[++cnt],1,rn);
        for(int i=1;i<=tot;i++){
            if(d[i].x0==d[i].x1 && t!=1) continue;
            d[i].x0=lower_bound(rk+1,rk+1+rn,d[i].x0)-rk;
            d[i].x1=lower_bound(rk+1,rk+1+rn,d[i].x1)-rk;
            insert_mx(root,1,rn,d[i].x0,d[i].x1,i);
            insert_mn(root,1,rn,d[i].x0,d[i].x1,i);
        }
        for(int i=0;i<num;i++){
            Mx=Mn=0;
            ask[i]=lower_bound(rk+1,rk+1+rn,ask[i])-rk;
            query(root,1,rn,ask[i]);
            printf("%lld
    ",max(abs(cal(Mx,ask[i])),abs(cal(Mn,ask[i]))));
        }
         
        return 0;
    } 
    
    既然选择了远方,便只顾风雨兼程
  • 相关阅读:
    js 数据图表
    yii query builder
    mysql if
    这又是起点
    [cookie篇]从cookie-parser中间件说起
    How to find and fix Bash Shell-shock vulnerability CVE-2014-6271 in unix like system
    AngularJS打印问题
    笔记本上班时间自动静音下班自动打开
    SCP命令
    Installing Ruby 1.9.3 on Ubuntu 12.04 Precise Pengolin (without RVM)
  • 原文地址:https://www.cnblogs.com/lindalee/p/11348926.html
Copyright © 2020-2023  润新知