Description FJ'sN(1 ≤N≤ 10,000) cows conveniently indexed 1 ..NAre standing in a line. Each cow has a positive integer height (which is a bit of secret). You are told only the heightH(1 ≤H≤ 1,000,000) of the tallest cow along with the indexIOf that cow. FJ has made a listR(0 ≤R≤ 10,000) lines of the form "cow 17 sees cow 34 ". this means that cow 34 is at least as tall as cow 17, and that every cow between 17 and 34 has a height that is strictly smaller than that of cow 17. For each cow from 1 ..N, Determine its maximum possible height, such that all of the information given is still correct. It is guaranteed that it is possible to satisfy all the constraints. Input Line 1: four space-separated integers:N,I,HAndR Lines 2 ..R+ 1: two distinct space-separated IntegersAAndB(1 ≤A,B≤N), Indicating that cowACan see cowB.Output Lines 1 ..N: LineIContains the maximum possible height of cowI.Sample Input 9 3 5 51 35 34 33 79 8 Sample output 545344555 The idea of the Line Segment tree is right. In the slot, the game won't go through eight rounds. I thought the algorithm was wrong and read discuss. Poj, you have a piece of exercise, and you can't speak out when making a mistake... Question: N steak teams, numbers X and Y for both of you. Ask X to see y, and the height of the middle ox is small. Locate The maximum possible height of a cow. Line Segment tree idea: first set the height of all cattle to the highest H, for the given interval X, Y, minus the values in (x, y) by 1. The output is equal to-=. # Include <iostream> # include <cstdio> # include <cstring> # include <algorithm> # include <limits. h> using namespace STD; const int maxn = 10000 + 100; int ll [maxn], RR [maxn]; long N, H, R, I; long long add [maxn <2], ANS [maxn]; struct node {int L, R; int sum;} t [maxn <2]; void Pushdown (int rs) // update down the accumulated value of lazy {If (add [RS]) {Add [RS <1] + = add [RS]; add [RS <1 | 1] + = add [RS]; add [RS] = 0 ;}} void build (int rs, int L, int R) {T [RS]. L = L; t [RS]. R = r; add [RS] = 0; If (L = r) {T [RS]. sum = H; return;} int mid = (L + r)> 1; build (RS <1, L, mid); Build (RS <1 | 1, mid + 1, R);} void Update (int l, int R, int RS) // update operation {// cout <"fuck" <t [RS]. L <"" <t [RS]. r <Endl; If (T [RS]. l> = L & T [RS]. r <= r) {// cout <"fuck2" <Endl; add [RS] + = 1; return;} Pushdown (RS ); int mid = (T [RS]. L + T [RS]. r)> 1; if (L <= mid) Update (L, R, RS <1); If (r> mid) Update (L, R, RS <1 | 1);} int query (int K, in T RS) {If (T [RS]. L = T [RS]. r) {return T [RS]. sum-= add [RS];} Pushdown (RS); int mid = (T [RS]. L + T [RS]. r)> 1; if (k <= mid) return query (K, RS <1); else return query (K, RS <1 | 1 );} int main () {int U, V; while (~ Scanf ("% i64d % i64d % i64d % i64d", & N, & I, & H, & R) {build (1, 1, n); int K = 0; while (r --) {scanf ("% d", & U, & V); If (u> V) Swap (u, v); int flag = 1; for (INT I = 0; I <K; I ++) // judge the duplicate edge, make sure to prevent this in poj {If (u = ll [I] & V = RR [I]) {flag = 0; break ;}} if (! Flag) continue; ll [k] = u; RR [k] = V; k ++; If (V-u = 1) // adjacent words do not need to update the continue; Update (U + 1, V-1, 1); // note that the value of the open interval is updated} For (INT I = 1; I <= N; I ++) ans [I] = query (I, 1); For (INT I = 1; I <= N; I ++) printf ("% i64d \ n", ANS [I]);} return 0 ;}
|