zoukankan      html  css  js  c++  java
  • bzoj 1171 大sz的游戏& 2892 强袭作战 (线段树+单调队列+永久性flag)

    大sz的游戏

    Time Limit: 50 Sec  Memory Limit: 357 MB
    Submit: 536  Solved: 143
    [Submit][Status][Discuss]

    Description

    大sz最近在玩一个由星球大战改编的游戏。话说绝地武士当前共控制了N个星球。但是,西斯正在暗处悄悄地准备他们的复仇计划。绝地评议会也感觉到了这件事。于是,准备加派绝地武士到各星球防止西斯的突袭。一个星球受到攻击以后,会尽快通知到总基地。需要的时间越长的星球就需要越多绝地武士来防御。为了合理分配有限的武士,大sz需要你帮他求出每个星球各需要多少时间能够通知到总基地。由于某种原因,N个星球排成一条直线,编号1至N。其中总基地建在1号星球上。每个星球虽然都是绝地武士控制的,但是上面居住的生物不一定相同,并且科技水平也不一样。第i个星球能收到并分析波长在[xi, yi]之间的信号,并且也能够发出在这个区间的信号,但是不能发出其他任何波长的信号。由于技术原因,每个星球只能发信号到比自己编号小的距离不超过L的星球。特别地,强大的总基地可以接收任何波长的信号。每个星球处理接收到的数据需要1个单位时间,传输时间可以忽略不计。

    Input

    第一行两个正整数N、L。接下来N-1行,总共第i行包含了三个正整数xi、yi、li,其中li表示第i个星球距离1号星球li,满足li严格递增。

    Output

    总共N-1行,每行一个数分别表示2到N号星球至少需要多少单位时间,总基地能够处理好数据,如果无法传到总基地则输出-1。

    Sample Input

    input1
    3 1
    1 2 1
    2 3 2
    input 2
    3 3
    1 2 1
    2 3 2

    Sample Output

    output1
    1
    2
    output2
    1
    1
    30%的数据满足N <=20000;
    100%的数据满足2 <=N<= 2.5*10^5、0<=xi,yi,li<=2*10^9,1<=L<=2*10^9,xi<=yi.

    HINT

     

    Source

     
    题解
        发现距离具有单调性质,所以可以想到单调性,将xi,xj抽象成一条线段,
        发现当两条线段有交集的时候并且,距离满足条件时是可以转移的,
        那么如何思考呢?
        发现可以将xi,xj离散化,这样的话,就可以在线段树一段区间中寻找最小值,
        但是出现一个问题,最小值是不能够删除的,就是距离不满足了,怎么删除
        无法做到,所以需要在每个点中开一个单调队列,这才是这道题目的难点。
        
        先了解一个概念,什么叫做永久性flag,对于普通的flag,是不是需要标记下传
        也就是说,标记不是固定的,二永久性标记,顾名思义就是不需要下传标记,
            

        比如红色线段是需要寻找的,那么对于包括这条线段的,并且是满足整条线段包括的

        我的代码中分为一个tr与一个bj数组,

        tr数组的意思是刚好完全包括这一段的,一个值,

        而bj表示子区间中含有这一段的,

        那么,在寻找中,如果被tr包括,tr可以直接更新,因为这段全部都是满足的。

        如果当前寻找的这一段是包括了bj那么bj中有子区间的值也一定被寻找段包括,所以可以更新,

        这样更新前维护单调性即可。

     1 #include<cstring>
     2 #include<cmath>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<cstdio>
     6 #include<map>
     7 #include<list>
     8 
     9 #define N 2000007
    10 #define inf 1000000007
    11 #define fzy pair<int,int>
    12 using namespace std;
    13 inline int read()
    14 {
    15     int x=0,f=1;char ch=getchar();
    16     while(ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    17     while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    18     return x*f;
    19 }
    20 
    21 int n,L,num,siz;
    22 int hd,tl,q[N],b[N],f[N];
    23 struct Node
    24 {
    25     int x,y,l;
    26 }a[N];
    27 list<fzy>tr[N],bj[N];
    28 map<int,int>p;
    29 
    30 
    31 void ins(int p,int l,int r,int x,int y,fzy zhi)
    32 {
    33     if (x<=l&&r<=y)
    34     {
    35         while(!tr[p].empty()&&tr[p].back().second>=zhi.second)
    36             tr[p].pop_back();
    37         tr[p].push_back(zhi);
    38         return;
    39     }
    40     
    41     while(!bj[p].empty()&&bj[p].back().second>=zhi.second)
    42         bj[p].pop_back();
    43     bj[p].push_back(zhi);
    44     
    45     int mid=(l+r)>>1;
    46     if (y<=mid) ins(p<<1,l,mid,x,y,zhi);
    47     else if (x>mid) ins(p<<1|1,mid+1,r,x,y,zhi);
    48     else ins(p<<1,l,mid,x,mid,zhi),ins(p<<1|1,mid+1,r,mid+1,y,zhi);
    49 }
    50 int query(int p,int l,int r,int x,int y,int wei)
    51 {
    52     int res;
    53     
    54     while(wei-tr[p].front().first>L&&!tr[p].empty())
    55         tr[p].pop_front();
    56     if (tr[p].empty()) res=inf;
    57     else res=tr[p].front().second;
    58     
    59     
    60     while(wei-bj[p].front().first>L&&!bj[p].empty()) bj[p].pop_front();
    61     if (x<=l&&r<=y)
    62     {
    63         if (!bj[p].empty()) res=min(res,bj[p].front().second);
    64         return res;
    65     }
    66     
    67     int mid=(l+r)>>1;
    68     if (y<=mid) res=min(res,query(p<<1,l,mid,x,y,wei));
    69     else if (x>mid) res=min(res,query(p<<1|1,mid+1,r,x,y,wei));
    70     else res=min(res,min(query(p<<1,l,mid,x,mid,wei),query(p<<1|1,mid+1,r,mid+1,y,wei)));
    71     return res;
    72 }
    73 int main()
    74 {
    75     n=read(),L=read();
    76     for (int i=1;i<n;i++)
    77         a[i].x=read(),a[i].y=read(),a[i].l=read(),b[++num]=a[i].x,b[++num]=a[i].y;
    78     sort(b+1,b+num+1);
    79     for (int i=1;i<=num;i++)
    80         if (b[i]!=b[i-1]) p[b[i]]=++siz;
    81     for (int i=1;i<n;i++)
    82         a[i].x=p[a[i].x],a[i].y=p[a[i].y];
    83     
    84     ins(1,1,siz,1,siz,make_pair(0,0));
    85     for (int i=1;i<n;i++)
    86     {
    87         f[i]=query(1,1,siz,a[i].x,a[i].y,a[i].l)+1;
    88         ins(1,1,siz,a[i].x,a[i].y,make_pair(a[i].l,f[i]));
    89     }
    90     for (int i=1;i<n;i++)
    91         printf("%d
    ",f[i]>=n?-1:f[i]);
    92 }
  • 相关阅读:
    爬虫例子及知识点(scrapy知识点)
    Xpath()语法
    yield和python(如何生成斐波那契數列)
    Python3导入cookielib失败
    使用Scrapy爬虫框架简单爬取图片并保存本地(妹子图)
    python使用cookielib库示例分享
    xpath中/和//的差别
    [洛谷P3320] SDOI2015 寻宝游戏
    [洛谷P3322] SDOI2015 排序
    [51nod 1830] 路径交
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8005168.html
Copyright © 2011-2022 走看看