BZOJ1595 [Usaco2008 Jan]人工湖

直接模拟。。。从最低的开始向两边拓展= =

 1 /**************************************************************
 2     Problem: 1595
 3     User: rausen
 4     Language: C++
 5     Result: Accepted
 6     Time:328 ms
 7     Memory:3932 kb
 8 ****************************************************************/
 9
10 #include <cstdio>
11
12 using namespace std;
13 typedef long long ll;
14 const int N = 1e5 + 5;
15 const ll inf = (ll) 1e18;
16
17 inline int read();
18
19 struct data {
20     ll w, h;
21     int pre, nxt;
22
23     inline void get(int x) {
24         w = read(), h = read();
25         pre = x - 1, nxt = x + 1;
26     }
27 } a[N];
28
29 int n, now;
30 ll now_ans, ans[N];
31
32 int main() {
33     int i;
34     n = read();
35     for (i = now = 1; i <= n; ++i) {
36         a[i].get(i);
37         if (a[i].h < a[now].h) now = i;
38     }
39     a[0].w = a[n + 1].w = 0, a[0].h = a[n + 1].h = inf, a[0].nxt = 1, a[n + 1].pre = n;
40 #define Pre a[now].pre
41 #define Nxt a[now].nxt
42     for (i = 1; i <= n; ++i) {
43         while (a[Pre].h < a[now].h) now = Pre;
44         while (a[Nxt].h < a[now].h) now = Nxt;
45         ans[now] = now_ans + a[now].w;
46         a[Pre].nxt = Nxt, a[Nxt].pre = Pre;
47         if (a[Pre].h < a[Nxt].h) {
48             now_ans += a[now].w * (a[Pre].h - a[now].h);
49             a[Pre].w += a[now].w, now = Pre;
50         } else {
51             now_ans += a[now].w * (a[Nxt].h - a[now].h);
52             a[Nxt].w += a[now].w, now = Nxt;
53         }
54     }
55     for (i = 1; i <= n; ++i)
56         printf("%lld\n", ans[i]);
57     return 0;
58 }
59
60 inline int read() {
61     static int x;
62     static char ch;
63     x = 0, ch = getchar();
64     while (ch < ‘0‘ || ‘9‘ < ch)
65         ch = getchar();
66     while (‘0‘ <= ch && ch <= ‘9‘) {
67         x = x * 10 + ch - ‘0‘;
68         ch = getchar();
69     }
70     return x;
71 }

时间: 2024-12-13 12:31:28

BZOJ1595 [Usaco2008 Jan]人工湖的相关文章

[BZOJ1595] [Usaco2008 Jan]人工湖(单调栈)

传送门 好难的题..至少对我来说. 这题就是模拟从最低的平台注水,然后将最低的填满以后从最低的平台向两边扩展,每次找最近的最低的平台h,然后将水填到h高度. 栈里存的是向外扩展的时候,有时会遇到高度递减的情况,这时并不能填水,但要把这些高度都递减(即扩展时的顺序)记录进栈,然后遇到一个比比水面高的平台h时,模拟倒水,水会挨个淹没最低的平台,即需要从栈顶一个一个出战计算淹没时间,直至栈顶平台高度>h,此时h入栈.重复执行就可算出答案. #include <cstdio> #include

1596: [Usaco2008 Jan]电话网络

1596: [Usaco2008 Jan]电话网络 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 601  Solved: 265[Submit][Status][Discuss] Description Farmer John决定为他的所有奶牛都配备手机,以此鼓励她们互相交流.不过,为此FJ必须在奶牛们居住的N(1 <= N <= 10,000)块草地中选一些建上无线电通讯塔,来保证任意两块草地间都存在手机信号.所有的N块草地按1..N 顺次

bzoj1596[Usaco2008 Jan]电话网络*

bzoj1596[Usaco2008 Jan]电话网络 题意: 在一棵树中选最少的点建塔,使得每个点都有塔或相邻点有塔.n≤10000. 题解: 贪心.dfs时对于每个当前点,在dfs完它的所有子节点后如果它以及它的儿子以及它的父亲没塔,则在它父亲处建塔. 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <queue> 5 #define inc(i

[bzoj1612][Usaco2008 Jan]Cow Contest奶牛的比赛_dfs

Cow Contest奶牛的比赛 bzoj-1612 Usaco-2008 Jan 题目大意:题目链接. 注释:略. 想法: 我们对于每个点dfs,看一下比这个点大的点加上比这个点小的点是否是n-1即可. 最后,附上丑陋的代码... ... #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N

[BZOJ1594] [Usaco2008 Jan]猜数游戏(二分 + 并查集)

传送门 题中重要信息,每堆草的数量都不一样. 可以思考一下,什么情况下才会出现矛盾. 1.如果两个区间的最小值一样,但是这两个区间没有交集,那么就出现矛盾. 2.如果两个区间的最小值一样,并且这两个区间有交集,那么这个最小值一定在交集中,但是如果这个交集被某个最小值较大的区间,或是一些最小值较大的区间的并集包含,那么也是矛盾的. 可以二分答案,将这些区间按照最小值从大到小排序,然后可以用线段树维护,也可以用并查集来搞. 下面是用并查集来搞的. 每到一个区间,可以将[l,r]中的f变成r+1,如果

【BZOJ】1596: [Usaco2008 Jan]电话网络

[算法]树上贪心 [题解] 因为一个点必须被覆盖,那么它如果没有被子树节点覆盖的话,就覆盖它的父节点. 从叶子开始贪心. 注意,如果它自己已经被选了就不需要选父节点了. #include<cstdio> #include<algorithm> #include<cstring> #include<cctype> using namespace std; const int maxn=10010; struct edge{int v,from;}e[maxn*

BZOJ 1596: [Usaco2008 Jan]电话网络

Description Farmer John决定为他的所有奶牛都配备手机,以此鼓励她们互相交流.不过,为此FJ必须在奶牛们居住的N(1 <= N <= 10,000)块草地中选一些建上无线电通讯塔,来保证任意两块草地间都存在手机信号.所有的N块草地按1..N 顺次编号. 所有草地中只有N-1对是相邻的,不过对任意两块草地A和B(1 <= A <= N; 1 <= B <= N; A != B),都可以找到一个以A开头以B结尾的草地序列,并且序列中相邻的编号所代表的草地

【bzoj1596/Usaco2008 Jan】电话网络——dfs

Description Farmer John决定为他的所有奶牛都配备手机,以此鼓励她们互相交流.不过,为此FJ必须在奶牛们居住的N(1 <= N <= 10,000)块草地中选一些建上无线电通讯塔,来保证任意两块草地间都存在手机信号.所有的N块草地按1..N 顺次编号. 所有草地中只有N-1对是相邻的,不过对任意两块草地A和B(1 <= A <= N; 1 <= B <= N; A != B),都可以找到一个以A开头以B结尾的草地序列,并且序列中相邻的编号所代表的草地

bzoj 1594: [Usaco2008 Jan]猜数游戏——二分+线段树

Description 为了提高自己低得可怜的智商,奶牛们设计了一个新的猜数游戏,来锻炼她们的逻辑推理能力. 游戏开始前,一头指定的奶牛会在牛棚后面摆N(1 <= N<= 1,000,000)堆干草,每堆有若干捆,并且没有哪两堆中的草一样多.所有草堆排成一条直线,从左到右依次按1..N编号,每堆中草的捆数在1..1,000,000,000之间. 然后,游戏开始.另一头参与游戏的奶牛会问那头摆干草的奶牛 Q(1 <= Q <= 25,000)个问题,问题的格式如下: 编号为Ql..Q