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

By 俞华程

题解

    发现距离具有单调性质,所以可以想到单调性,将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\n",f[i]>=n?-1:f[i]);
92 }
时间: 2024-10-12 10:54:58

bzoj 1171 大sz的游戏& 2892 强袭作战 (线段树+单调队列+永久性flag)的相关文章

BZOJ1171: 大sz的游戏&amp;BZOJ2892: 强袭作战

Description 大sz最近在玩一个由星球大战改编的游戏.话说绝地武士当前共控制了N个星球.但是,西斯正在暗处悄悄地准备他们的复仇计划.绝地评议会也感觉到了这件事.于是,准备加派绝地武士到各星球防止西斯的突袭.一个星球受到攻击以后,会尽快通知到总基地.需要的时间越长的星球就需要越多绝地武士来防御.为了合理分配有限的武士,大sz需要你帮他求出每个星球各需要多少时间能够通知到总基地.由于某种原因,N个星球排成一条直线,编号1至N.其中总基地建在1号星球上.每个星球虽然都是绝地武士控制的,但是上

【BZOJ-2892&amp;1171】强袭作战&amp;大sz的游戏 权值线段树+单调队列+标记永久化+DP

2892: 强袭作战 Time Limit: 50 Sec  Memory Limit: 512 MBSubmit: 45  Solved: 30[Submit][Status][Discuss] Description 在一个没有冬马的世界里,经历了学园祭后的春希着急着想要见到心爱的雪菜.然而在排队想见雪菜的fans太多了,春希一时半会凑不到雪菜面前. 作为高帅富,这样的问题怎么能难倒春希?春希从武也手中拿到了取自金闪闪宝库里的多啦A梦的传话筒,并且给每一个排队的fans都发了一个传话筒. 于

BZOJ 1012 线段树||单调队列

非常裸的线段树  || 单调队列: 假设一个节点在队列中既没有时间优势(早点入队)也没有值优势(值更大),那么显然不管在如何的情况下都不会被选为最大值. 既然它仅仅在末尾选.那么自然能够满足以上的条件. 线段树 #include "stdio.h" #include "string.h" struct node { int l,r,Max; }data[800010]; int Max(int a,int b) { if (a<b) return b; els

HDU 1540 &amp;&amp; POJ 2892 Tunnel Warfare (线段树,区间合并).

~~~~ 第一次遇到线段树合并的题,又被律爷教做人.TAT. ~~~~ 线段树的题意都很好理解吧.. 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1540 http://poj.org/problem?id=2892 ~~~~ 我的代码:200ms #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #defin

BZOJ 2588 Count on a tree (COT) 可持久化线段树

题目大意:查询树上两点之间的第k大的点权. 思路:树套树,其实是正常的树套一个可持久化线段树.因为利用权值线段树可以求区间第k大,然后再应用可持久化线段树的思想,可以做到区间减法.详见代码. CODE: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 100010 #define NIL (tree[0]) using name

[BZOJ1171][BZOJ2892]大sz的游戏

试题描述 大sz最近在玩一个由星球大战改编的游戏.话说绝地武士当前共控制了N个星球.但是,西斯正在暗处悄悄地准备他们的复仇计划.绝地评议会也感觉到了这件事.于是,准备加派绝地武士到各星球防止西斯的突袭.一个星球受到攻击以后,会尽快通知到总基地.需要的时间越长的星球就需要越多绝地武士来防御.为了合理分配有限的武士,大sz需要你帮他求出每个星球各需要多少时间能够通知到总基地.由于某种原因,N个星球排成一条直线,编号1至N.其中总基地建在1号星球上.每个星球虽然都是绝地武士控制的,但是上面居住的生物不

BZOJ 3207: 花神的嘲讽计划Ⅰ( hash + 可持久化线段树 )

O(NK)暴力搞出所有子串的哈希值, 然后就对哈希值离散化建权值线段树, 就是主席树的经典做法了.总时间复杂度O(NK+(N+Q)logN) -------------------------------------------------------------------------- #include<cstdio> #include<algorithm> #include<cstring> #include<cctype> using namespa

BZOJ 3439 Kpm的MC密码 Trie+可持久化线段树

题目大意:定义一种串,如果一个串是另一个串的后缀,那么这个串称作kpm串.问一个串的标号第k大的kpm串是多少. 思路:将所有的串翻转之后变成前缀,全都插进一个Trie树中.每个节点维护一个last指针,表示最后一次更新的可持久化线段树的指针,如果再有串经过这里,就继续更新last指针.最后只需要查询last指针中的东西就可以了. CODE: #include <cstdio> #include <cstring> #include <iostream> #includ

BZOJ 1568: [JSOI2008]Blue Mary开公司(超哥线段树)

1568: [JSOI2008]Blue Mary开公司 Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 1080  Solved: 379[Submit][Status][Discuss] Description Input 第一行 :一个整数N ,表示方案和询问的总数. 接下来N行,每行开头一个单词“Query”或“Project”. 若单词为Query,则后接一个整数T,表示Blue Mary询问第T天的最大收益. 若单词为Project,则