2200+专项:E. Award Ceremony(滚榜数量 思维 树状数组)

original: http://codeforces.com/problemset/problem/730/E

question:

Like ACM, 4 hours after beginning, the list of user stopped updating.

Now give you the points for n competitors after stopping, and the points they got in the last hour.

And give you the list for first four hours, and you can let one’s point become final point, the rating of the competitor will change, the difference is X X .

You need to calculate the maximum of X \sum_X .

analyze:

If two points both become higher, it’s obvious that change from low to high. And vice versa.

Let’s consider one become higher and the other become lower. You could enumerate all cases that whichever change first isn’t matter.

So, we can let all points change which become higher ,and than the others.

#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int maxn=1009;

int tr[10009];
void add(int p,int v){
    while(p<10009){
        tr[p]+=v;
        p+=p&-p;
    }
}
int query(int p){
    int ans=0;
    while(p>0){
        ans+=tr[p];
        p-=p&-p;
    }
    return ans;
}

struct node{
    int id,a,b;
}e[maxn];

struct TMP{
    int id,p;
    bool operator<(const TMP & R)const{
        return p<R.p||p==R.p&&id>R.id;
    }
}tmp[maxn],tmp0;

int a[maxn],b[maxn];
int v1[maxn],v2[maxn];
bool cmp1(int i,int j){
    return a[i]<a[j];
}
bool cmp2(int i,int j){
    return a[i]>a[j];
}

int main(){
    int n;scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d%d",&e[i].a,&e[i].b),e[i].id=i;
    for(int i=1;i<=n;i++){
        tmp[2*i].id=e[i].id;
        tmp[2*i].p=e[i].a;
        tmp[2*i-1].id=e[i].id;
        tmp[2*i-1].p=e[i].a+e[i].b;
    }
    sort(tmp+1,tmp+1+2*n);
    for(int i=1;i<=n;i++){
        tmp0.id =i,tmp0.p=e[i].a;
        a[i]=lower_bound(tmp+1,tmp+1+2*n,tmp0)-tmp;
        tmp0.id =i,tmp0.p=e[i].a+e[i].b;
        b[i]=lower_bound(tmp+1,tmp+1+2*n,tmp0)-tmp;
    }
    int ans=0;

    int top1=0,top2=0;
    for(int i=1;i<=n;i++){
        if(e[i].b>0){
            v1[++top1]=i;
            add(a[i],1);
        }
        else if(e[i].b<0){
            v2[++top2]=i;
            add(a[i],1);
        }
        else
            add(a[i],1);
    }
    sort(v1+1,v1+1+top1,cmp1);
    sort(v2+1,v2+1+top2,cmp2);
    for(int i=1;i<=top1;i++){
        int res=0;
        int p=v1[i];
        ans+=query(b[p]-1)-query(a[p]);
        add(a[p],-1);
        add(b[p],1);
    }
    for(int i=1;i<=top2;i++){
        int res=0;
        int p=v2[i];
        ans+=query(a[p]-1)-query(b[p]);
        add(a[p],-1);
        add(b[p],1);
    }
    printf("%d\n",ans);
}

猜你喜欢

转载自blog.csdn.net/jk_chen_acmer/article/details/90550055