http://poj.org/problem?id=2481
Cows
Time Limit: 3000MS |
|
Memory Limit: 65536K |
Total Submissions: 14762 |
|
Accepted: 4886 |
Description
Farmer John ' s cows has discovered that the clover growing along the ridge of the hill (which we can think of as a One-dim Ensional number line) in he field is particularly good.
Farmer John had N cows (we number the cows from 1 to N). Each of Farmer John's N cows have a range of clover that she particularly likes (these ranges might overlap). The ranges is defined by a closed interval [s,e].
But some cows is strong and some is weak. Given Cows:cowi and COWJ, their favourite clover range is [Si, Ei] and [Sj, Ej]. If Si <= Sj and Ej <= Ei and Ei-si > EJ-SJ, we say that cowi are stronger than COWJ.
For each cow, how many cows is stronger than her? Farmer John needs your help!
Input
The input contains multiple test cases.
For each test case, the first line is a integer n (1 <= n <=), which is the number of cows. Then come N lines, the i-th of which contains the Integers:s and E (0 <= S < e <=) specifying the start end L Ocation respectively of a range preferred by some cow. Locations is given as distance from the start of the ridge.
The end of the input contains a single 0.
Output
For each test case, output one line containing n space-separated integers, the i-th of which specifying the number of cows That is stronger than COWI.
Sample Input
31 20 33 40
Sample Output
1 0 0
Hint
Huge input and output,scanf and printf is recommended.
Source
POJ Contest,author:[email protected]
idea: Tree-like array
Analysis:
1 topics given n the range of cows, and then asked how many cows are stronger than each cow
2 According to the topic if the interval of the ox i is [Si, Ei], the range of the Bull J is [Sj, Ej] then the ox i is stronger than the bull J, then there is Si <= Sj && Ei >= Ej && ei-si > EJ-SJ;
3 then according to the above conditions, we should first order the range of n cows "according to s from small to large, the same s according to E from large to small sort"
4 Obviously after the sequencing we were able to meet Si <= Sj && Ei >= Ej, but we should be awareei-si > EJ-SJindicates that the sequence cannot be equal after the order is completed.
5 We use E to do a tree-like array, if the front and back two is quite so direct update can
Code:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm>using namespace std;const int MAXN = 100010;struct node{int S; int E; int number; BOOL operator< (const node& tmp) const{if (S < TMP). S) return true; else if (S = = tmp. S && E > tmp. E) return true; return false; } bool operator== (const node& tmp) const{return S = = tmp. S && E = = tmp. E }}; Node node[maxn];int n;int ans[maxn];int treenum[maxn];int lowbit (int x) {return x& (-X);} int getsum (int x) {int sum = 0; while (x) {sum + = treenum[x]; X-= Lowbit (x); } return sum;} void Add (int x, int val) {while (X < MAXN) {Treenum[x] + = val; x + = Lowbit (x); }}void solve () {memset (ans, 0, sizeof (ans)); memset (treenum, 0, sizeof (treenum)); Sort (node, node+n); for (int i = 0; i < n; i++) {int id = node[i]. E if (i &&Amp Node[i] = = Node[i-1]) Ans[node[i].number] = Ans[node[i-1].number]; else Ans[node[i].number] + = I-getsum (id-1); Add (ID, 1); } printf ("%d", ans[0]); for (int i = 1; i < n; i++) printf ("%d", ans[i]); Puts ("");} int main () {while (scanf ("%d", &n) && N) {for (int i = 0; i < n; i++) {scanf ("%d%d", &node[i]. S, &node[i]. E); Node[i].number = i; } solve (); } return 0;}
follow S,e in E from large to small, if E equals-s from small to large sort.
#include <stdio.h> #include <stdlib.h> #include <string.h> #define NMAX 100010#define Max (A, b) (a>b A:B) #define Min (A, B) (a<b?a:b) struct cow{int s,e,id;} Cow[nmax];int ans[nmax];int Cnt[nmax];int maxn = -1;//comparison function, according to e from large to small, s small to large int cmp (const void * A, const void * b) {struct COW *c = (struct COW *) a;struct COW *d = (struct COW *) b;if (c->e = = d->e) {return c->s-d->s;} Elsereturn D->e-c->e;} The three functions of the tree array, one is to find the last 1 position of X, to add a number in a position, to find all the numbers before NUM and these three functions int lowbit (int x) {return x& (x^ (x-1));} void Add (int pos) {while (pos <= MAXN + 1) {Ans[pos] + +;p OS + = Lowbit (pos);}} int sum (int num) {int sum = 0;while (num > 0) {sum + = ans[num];num-= lowbit (num);} return sum;} int main () {int n;while (scanf ("%d", &n) && n) {maxn = -1;for (int i = 1; I <= n; + + i) {scanf ("%d%d", &c OW[I].S, &cow[i].e); cow[i].id = I;MAXN = Max (MAXN, COW[I].E);} memset (ans, 0, sizeof (ans)), qsort (cow + 1, N, sizeof (cow[0]), CMP), for (int i = 1; I <= n; + + i) {if (cow[I].s = = Cow[i-1].s && cow[i].e = = cow[i-1].e)//equal words, not counted {cnt[cow[i].id] = cnt[cow[i-1].id];} else//Otherwise you can find the number of all cows covering this interval, because of the order, only in front cnt[cow[i].id] = SUM (cow[i].s + 1), add (Cow[i].s + 1);//Add the starting point of this interval to the tree array}for (int i = 1; I < n; + + i) {printf ("%d", Cnt[i]);} printf ("%d\n", Cnt[n]);} return 0;}
idea: Line segment tree + single point update
Analysis:
1 topics given n the range of cows, and then asked how many cows are stronger than each cow
2 According to the topic if the interval of the ox i is [Si, Ei], the range of the Bull J is [Sj, Ej] then the ox i is stronger than the bull J then there is Si <= Sj && Ei >= Ej && si-ei! = sj-ej;
3 then according to the above conditions, we should first to the N-cow of the interval sort "according to s small to large, the same s according to E from the big to the small sort", and then you can use the line tree to beg.
4 There is a place to note that when the order is completed after the next two equal, then only need to update the sum.
Code:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm>using namespace STD; #define MAXN 100010struct segment{int x; int y; int number; BOOL operator== (const Segment &a) const{if (a.x = = x && a.y = = y) return true; return false; }}; Segment s[maxn];struct node{int left; int right; int sum;}; Node node[4*maxn];int n;int Vis[maxn];bool cmp (Segment s1, Segment S2) {if (s1.x < s2.x) return true; else if (s1.x = = s2.x && s1.y > S2.y) return true; return false;} void Buildtree (int left, int. right, int pos) {node[pos].left = left; Node[pos].right = right; node[pos].sum = 0; if (left = = right) return; int mid = (left+right) >>1; Buildtree (left, Mid, pos<<1); Buildtree (Mid+1, right, (pos<<1) +1);} int query (int left, int right, int pos) {if (Node[pos].left = = Left && Node[pos].right = = right) return nod E[pos].sum; int mid = (Node[pos].left+node[pos].right) >>1; if (right <= mid) return to query (left, right, pos<<1); else if (Left > Mid) return query (left, right, (pos<<1) +1); else return query (left, Mid, pos<<1) +query (Mid+1, right, (pos<<1) +1);} void Update (int index, int pos) {if (Node[pos].left = = node[pos].right) {node[pos].sum++; Return } int mid = (node[pos].left+node[pos].right) >>1; if (index <= mid) update (index, pos<<1); else Update (index, (pos<<1) +1); Node[pos].sum = node[pos<<1].sum+node[(pos<<1) +1].sum;} int main () {while (scanf ("%d", &n) && N) {memset (Vis, 0, sizeof (VIS)); for (int i = 0; i < n; i++) {scanf ("%d%d", &s[i].x, &S[I].Y); S[i].number = i; } sort (S, s+n, CMP); Buildtree (1, MAXN, 1); for (int i = 0; i < n; i++) {if (i && s[i] = = S[i-1]) Vis[s[i].number] = Vis[s[i-1].numbeR]; else Vis[s[i].number] + = query (S[i].y, MAXN, 1); Update (S[I].Y, 1); } printf ("%d", vis[0]); for (int i = 1; i < n; i++) printf ("%d", vis[i]); printf ("\ n"); } return 0;}
The currently inserted segment can completely overwrite the presence of several segment tree arrays HDU 5372 Segment Game
http://blog.csdn.net/acm_10000h/article/details/47907605
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Each output has several segments that can completely cover larger than itself and hdu5372 the opposite tree array or segment tree POJ 2481 cows