bzoj1862: [Zjoi2006]GameZ游戏排名系统

来源:互联网 发布:aws sdk for java 编辑:程序博客网 时间:2024/05/19 00:37

传送门
又是splay模板题
对于字符串我们可以采用哈希值进行比较。
当哈希值相同时全文比较。

#include<cmath>#include<cstdio>#include<cstring>#include<cstdlib>#include<iostream>#include<algorithm>#define mo 985003#define N 250250 using namespace std;int x,rt,sz,tot,n,head[mo+5];char ch[15];struct data1{    int v,tim,nxt;    char ch[10];}hash[N];struct data2{    int l,r,v,sz,rnd,tim;    char ch[10];}t[N];void update(int k){    t[k].sz=t[t[k].l].sz+t[t[k].r].sz+1;}void rturn(int &k){    int tmp=t[k].l;    t[k].l=t[tmp].r;    t[tmp].r=k;    t[tmp].sz=t[k].sz;     update(k);    k=tmp;}void lturn(int &k){    int tmp=t[k].r;    t[k].r=t[tmp].l;    t[tmp].l=k;    t[tmp].sz=t[k].sz;     update(k);    k=tmp;}bool cmp(char a[],char b[]){    int tmp=max(strlen(a),strlen(b));    for (int i=1;i<tmp;i++)        if (a[i]!=b[i]) return 0;    return 1;}int Hash(char ch[]){    int s=0,len=strlen(ch);    for (int i=1;i<len;i++)        s=(s*27+ch[i]-'A'+1)%mo;    return s;}void del(int &k,int x,int tim){    if (t[k].v==x){        if (t[k].tim==tim){            if (t[k].l*t[k].r==0) k=t[k].l+t[k].r;            else if (t[t[k].l].rnd<t[t[k].r].rnd){                rturn(k); del(k,x,tim);             }            else{                lturn(k); del(k,x,tim);            }        }        else if (tim>t[k].tim){            t[k].sz--; del(t[k].l,x,tim);        }        else{            t[k].sz--; del(t[k].r,x,tim);        }    }    else if (x<t[k].v){        t[k].sz--; del(t[k].l,x,tim);    }    else{        t[k].sz--; del(t[k].r,x,tim);    }}void ins(int &k,char ch[],int x,int tim){    if (!k){        k=++sz;        t[k].v=x;        t[k].sz=1;        t[k].rnd=rand();        memcpy(t[k].ch,ch,strlen(ch));        t[k].tim=tim;        return;    }    t[k].sz++;    if (x<=t[k].v){        ins(t[k].l,ch,x,tim);        if (t[t[k].l].rnd<t[k].rnd) rturn(k);    }    else{        ins(t[k].r,ch,x,tim);        if (t[t[k].r].rnd<t[k].rnd) lturn(k);    }}void insert(char ch[],int x,int tim){    int k=Hash(ch),i=head[k];    while (i){        if (cmp(hash[i].ch,ch)){            del(rt,hash[i].v,hash[i].tim);            hash[i].tim=tim;            hash[i].v=x;            ins(rt,ch,x,tim);            return;        }        i=hash[i].nxt;    }    hash[++tot].tim=tim;    hash[tot].v=x;    memcpy(hash[tot].ch,ch,strlen(ch));    hash[tot].nxt=head[k];    head[k]=tot;    ins(rt,ch,x,tim); }int get(char ch[]){    int k=Hash(ch),i=head[k];    while (i){        if (cmp(hash[i].ch,ch)) return i;        i=hash[i].nxt;    }}int getrk(int k,int x,int tim){    if (!k) return 0;    if (t[k].v==x){        if (t[k].tim>tim) return getrk(t[k].r,x,tim);        if (t[k].tim==tim) return t[t[k].r].sz+1;        return 1+t[t[k].r].sz+getrk(t[k].l,x,tim);    }    if (t[k].v<x) return getrk(t[k].r,x,tim);    return 1+t[t[k].r].sz+getrk(t[k].l,x,tim);}void ask1(char ch[]){    int t=get(ch);    printf("%d\n",getrk(rt,hash[t].v,hash[t].tim));}int index(int k,int x){    if (t[t[k].r].sz+1==x) return k;    if (x<=t[t[k].r].sz) return index(t[k].r,x);    return index(t[k].l,x-1-t[t[k].r].sz);}void ask2(char ch[]){    int s=0,len=strlen(ch);    for (int i=1;i<len;i++)        s=s*10+ch[i]-'0';    for (int i=s;i<=tot&&i<=s+9;i++){        printf("%s",t[index(rt,i)].ch+1);        if (i<tot&&i<s+9) printf(" ");    }    puts("");}int main(){    scanf("%d",&n);    for (int i=1;i<=n;i++){        scanf("%s",ch);        if (ch[0]=='+'){            scanf("%d",&x);            insert(ch,x,i);        }        else if (ch[1]>='A'&&ch[1]<='Z')            ask1(ch);        else ask2(ch);    }}
阅读全文
0 0
原创粉丝点击