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;
}