1003 线段树树状数组区间覆盖
算法:
比赛时是对线段长度从大到小排序,一次插入查询。一直WA。
赛后证明这种算法是错误的。
比如1 6 5 7 6 10这组数据就无法通过。
正确的算法应该是对线段的x从小到大排序,Y从大到小排序。
用线段树或树状数组维护区间和都可。
View Code
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<map> #include<iostream> #include<algorithm> #include<vector> using namespace std; struct node { int left, right; int num; int lazy; }seg[4000010]; int N, M; struct flower { int a,b, c; bool operator < (const flower &A) const { // if ( abs(A.b - A.a) != abs(b - a) ) // return abs(A.b - A.a) < abs(b-a); if( a != A.a ) return a < A.a; else return b > A.b; } }p[201000]; int v[400010]; int an[400010]; void build(int l, int r, int root) { int mid = (l + r) / 2; seg[root].left = l; seg[root].right = r; seg[root].num = 0; seg[root].lazy = 0; if( l == r ) { return; } build(l,mid,root*2); build(mid+1,r,root*2+1); } void update(int x) { seg[x * 2].lazy += seg[x].lazy; seg[x * 2].num += seg[x].lazy; seg[x * 2 + 1].lazy += seg[x].lazy; seg[x * 2 + 1].num += seg[x].lazy; seg[x].lazy = 0; } void add( int root, int u, int v, int val) { int mid = (seg[root].left + seg[root].right) / 2; if( seg[root].left == u && v == seg[root].right ) { seg[root].lazy += val; seg[root].num += val; return; } if( seg[root].lazy != 0 ) update( root ); if( u > mid ) add( root * 2 + 1, u, v, val); else if( v <= mid ) add( root * 2, u, v, val); else { add( root * 2, u, mid, val); add( root * 2 + 1, mid + 1, v,val); } } int sum( int root,int u, int v) { int mid = (seg[root].left + seg[root].right) / 2; if( seg[root].left == u && seg[root].right == v ) { return seg[root].num; } if( seg[root].lazy != 0 ) update(root); if( u > mid ) return sum( root * 2 + 1, u, v); else if( v <= mid ) return sum( root * 2, u, v); else { return min(sum( root * 2, u, mid), sum( root * 2 + 1, mid + 1, v)); } } int main( ) { int cnt; while( scanf("%d",&N) != EOF ) { cnt = 0; for( int i = 1; i <= N; i++) { scanf("%d%d",&p[i].a,&p[i].b); p[i].c = i; v[cnt++] = p[i].a; v[cnt++] = p[i].b; } sort(v, v + cnt); sort(p + 1, p + N + 1); cnt = unique(v, v + cnt) - v ; build(0,cnt,1); for( int i = 1; i <= N; i++) an[i] = 0; for( int i = 1; i <= N; i++) { if( i != 1 && p[i].a == p[i-1].a && p[i].b == p[i-1].b ) { an[p[i].c] = an[p[i-1].c]; int x = lower_bound(v, v + cnt, p[i].a) - v; int y = lower_bound(v, v + cnt, p[i].b) - v; add(1, x, y, 1); continue; } int x = lower_bound(v, v + cnt, p[i].a) - v; int y = lower_bound(v, v + cnt, p[i].b) - v; an[p[i].c] = sum(1, x, y); add(1, x, y, 1); } printf("%d",an[1]); for( int i = 2; i <= N; i++) { printf(" %d",an[i]); } puts(""); } return 0; }
posted on 2012-08-16 19:21 more think, more gains 阅读(316) 评论(0) 编辑 收藏 举报