P4291 [HAOI2008]排名系统

Posted lltyyc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P4291 [HAOI2008]排名系统相关的知识,希望对你有一定的参考价值。

传送门

怎么主要写的都是平衡树,这种查询排名,查询第 $K$ 大的操作直接权值线段树就行了

把读入的数据离散化一波,然后开个 $map$ 维护每个人最后一次插入时在线段树上的位置,直接线段树维护就完事了

查询排名就询问大于它的节点数量,查询第 $K$ 大直接线段树上二分

就是数据格式比较恶心,细节有点多

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
using namespace std;
typedef long long ll;
inline int read()

    int x=0,f=1; char ch=getchar();
    while(ch<0||ch>9)  if(ch==-) f=-1; ch=getchar(); 
    while(ch>=0&&ch<=9)  x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); 
    return x*f;

const int N=5e5+7;
int n;
struct dat
    int scr,tim; string nam; char opt;
    inline bool operator < (const dat &tmp) const 
        return scr!=tmp.scr ? scr<tmp.scr : tim>tmp.tim;
    
c[N],d[N];
map <string,int> pre;
int t[N<<2],pos,v,res;
void add(int o,int l,int r)

    t[o]+=v; if(l==r) return;
    int mid=l+r>>1;
    if(pos<=mid) add(o<<1,l,mid);
    else add(o<<1|1,mid+1,r);

void query_rnk(int o,int l,int r)

    if(l==r) return;
    int mid=l+r>>1;
    if(pos<=mid) query_rnk(o<<1,l,mid),res+=t[o<<1|1];
    else query_rnk(o<<1|1,mid+1,r);

void query(int o,int l,int r)

    if(l==r)  res=l; return; 
    int mid=l+r>>1;
    if(v>t[o<<1|1]) v-=t[o<<1|1],query(o<<1,l,mid);
    else query(o<<1|1,mid+1,r);

inline int Val(string s)

    int m=s.size(),res=0;
    for(int i=0;i<m;i++) res=res*10+s[i]-0;
    return res;

int main()

    n=read();
    for(int i=1;i<=n;i++)
    
        cin>>d[i].opt>>d[i].nam;
        if(d[i].opt==+) d[i].scr=read();
        d[i].tim=i; c[i]=d[i];
    
    sort(d+1,d+n+1); int tot=0;
    for(int i=1;i<=n;i++)
    
        if(c[i].opt==+)
        
            pos=pre[c[i].nam];
            if(pos) v=-1,add(1,1,n);
            else tot++;
            pos=lower_bound(d+1,d+n+1,c[i])-d;
            v=1; add(1,1,n); pre[c[i].nam]=pos;
            continue;
        
        if(c[i].nam[0]>9||c[i].nam[0]<0)
        
            res=0; pos=pre[c[i].nam]; query_rnk(1,1,n);
            printf("%d\n",res+1); continue;
        
        for(int k=1,j=Val(c[i].nam); k<=10&&j<=tot; k++,j++)
        
            v=j; res=0; query(1,1,n);
            cout<<d[res].nam; printf(" ");
        
        printf("\n");
    
    return 0;

 

以上是关于P4291 [HAOI2008]排名系统的主要内容,如果未能解决你的问题,请参考以下文章

数据结构(Splay平衡树):HAOI2008 排名系统

[HAOI2008] 排名系统

[haoi2008]排名系统

Bzoj1056--Haoi2008排名系统

bzoj1056 [HAOI2008]排名系统updating

●BZOJ 4566 [Haoi2016]找相同字符