http://poj.org/problem?id=2481
(1)对树状数组不熟练,但本题是最基本的树状数组。
(2)和星星那题本质一样,求比 x 大的其他已经入树的 x 的个数。只是多了一个排序处理
而已。
(3)之前没有进行排序,工作量特别大,效率很低,而且变量特别多,理解起来也比较吃力。
所以,排序处理是十分必要的。这里附上超时的代码。
具体代码:
View Code
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int maxn=101000; int n; int ar[maxn], ans[maxn]; struct node { int x, y, i; }data[maxn]; bool operator<(const node &a, const node &b) { if(a.y==b.y) return a.x<b.x; return a.y>b.y; } int lowbit(int x) { return x&(-x); } int sum(int x) { int s=0; while(x>0) { s+=ar[x]; x-=lowbit(x); } return s; } void update(int x) { while(x<maxn) { ar[x]++; x+=lowbit(x); } } int main() { int i, j; while(scanf("%d", &n)!=EOF, n) { memset(ar, 0, sizeof(ar)); for(i=0;i<n;i++) { scanf("%d%d", &data[i].x, &data[i].y); data[i].i=i; } sort(data, data+n); for(i=0;i<n;i++) { if(i&&data[i].x==data[i-1].x&&data[i].y==data[i-1].y) { ans[data[i].i]=ans[data[i-1].i]; } else { ans[data[i].i]=sum(data[i].x+1); } update(data[i].x+1); } printf("%d", ans[0]); for(i=1;i<n;i++) printf(" %d", ans[i]); printf("\n"); } return 0; }
超时代吗:
View Code
#include<stdio.h> #include<string.h> #include<algorithm> #define lson l, m, rt<<1 #define rson m+1, r, rt<<1|1 using namespace std; const int Inf=1<<28; const int N=101000; int x[N], y[N], sum[N<<2], mark[N<<2]; int l1[N<<2], r1[N<<2], l2[N<<2], r2[N<<2]; int n; void pushdown(int n, int rt) { if(mark[rt]) { mark[rt<<1]+=mark[rt]; mark[rt<<1|1]+=mark[rt]; sum[rt<<1]+=mark[rt]*(n-n/2); sum[rt<<1|1]+=mark[rt]*(n/2); mark[rt]=0; } } void pushup(int rt) { l1[rt]=max(l1[rt<<1], l1[rt<<1|1]); r1[rt]=min(r1[rt<<1], r1[rt<<1|1]); l2[rt]=min(l2[rt<<1], l2[rt<<1|1]); r2[rt]=max(r2[rt<<1], r2[rt<<1|1]); } void build(int l, int r, int rt) { mark[rt]=0; sum[rt]=0; l1[rt]=0, r1[rt]=0; l2[rt]=-Inf, r2[rt]=Inf; if(l==r) return ; int m=l+r>>1; build(lson); build(rson); } void update1(int a, int b, int i, int l, int r, int rt) { if(l1[rt]<=a&&b<=r1[rt]&&b-a<r1[rt]-l1[rt]) { sum[i]+=l-r+1; return ; } if(l==r) return ; int m=l+r>>1; update1(a, b, i, lson); update1(a, b, i, rson); } void update2(int a, int b, int l, int r, int rt) { if(a<=l2[rt]&&r1[rt]<=b&&r2[rt]-l2[rt]<b-a) { mark[rt]+=1; sum[rt]+=(l-r+1)*mark[rt]; return ; } if(l==r) return ; int m=l+r>>1; update2(a, b, lson); update2(a, b, rson); } void insert(int p, int a, int b, int l, int r, int rt) { if(l==r) { l1[rt]=a, r1[rt]=b; l2[rt]=a, r2[rt]=b; return ; } int m=l+r>>1; if(p<=m) insert(p, a, b, lson); else insert(p, a, b, rson); pushup(rt); } void search(int l, int r, int rt) { pushdown(r-l+1, rt); if(l==r) { printf("%d ", sum[rt]); return ; } int m=l+r>>1; search(lson); search(rson); pushup(rt); } int main() { int i, j; while(scanf("%d", &n)!=EOF, n) { build(1, n, 1); for(i=1;i<=n;i++) { scanf("%d%d", &x[i], &y[i]); update1(x[i], y[i], i, 1, n, 1); update2(x[i], y[i], 1, n, 1); insert(i, x[i], y[i], 1, n, 1); } search(1, n, 1); printf("\n"); } return 0; }
