【bzoj1862】[ZJOI2006]GameZ游戏排名系统

来源:互联网 发布:c语言打爱心 编辑:程序博客网 时间:2024/05/24 15:41

这道题我一定要吐槽!
简直醉了这道题,我调了整整半天。
从下午3点调到了晚上八点,其实尽管我写的特别丑,但是我差不多6点吃饭之前就写对了,交上去WA,之后改了几个地方实际AC了,但是我并没有交,而是要来了数据换cena测,在测的时候可能是乱复制粘贴搞得我insert函数里的return写成了int,然后崩溃的几个小时就开始了,我用cena+面对数据编程1个多小时发现没有问题,但用cena就是会崩溃访问无效内存,后来我发现了那个错误,改了回来之后因为想得到feedback,我没有在bzoj上交,而是去洛谷交了,结果TLE了三个点!!!当晚立马发说说,说自己splay人傻自带大常数,发现题解里有个人用递归版的splay过了(话说我真的第一次见到递归版的splay,以前只听zyz说过),但是复制粘贴他的程序测了一遍发现他根本就是个TLE的,然后我尝试把map换成trie树,还是不过,弃题去睡了,然后第二天去学校的路上突然想到洛谷主站是不开O2的,但是bzoj是开O2的,突然懂了,心中一万头草泥马奔过,回学校立马上大牛分站交了一发,我去比递归版的那个常数都小,简直要哭了
但是交在bzoj上收获了了人生中的第一个PE,每次询问排名的最后多打了一个空格,用子树大小控制了一下,成功的AC了,泪奔.
好了说点正经的,贴一下题解QAQ,其实就是hash+Splay啦,昨天燃起学treap的想法今天过了之后又熄灭了(笑),用map不会卡常就尽情的用咯,感觉hash的话250000hash函数选的不好也是可能冲突的把,双hash说不定比map还慢= =(其实当然不会,只是自我安慰).

#include<cstdio>#include<iostream>#include<cstring>#include<string>#include<algorithm>#include<map>using namespace std;const int N=250010,inf=0x7fffffff;int n,m,sz,root,tot,ed;int ch[N][2],fa[N],size[N],key[N],score[N];map<string,int>hs;map<int,string>ys;string name;inline void clear(int x){ch[x][0]=ch[x][1]=fa[x]=size[x]=key[x]=0;}inline int get(int x){return ch[fa[x]][1]==x;}inline void updata(int x){if (x)size[x]=(ch[x][0]?size[ch[x][0]]:0)+(ch[x][1]?size[ch[x][1]]:0)+1;}inline void rotate(int x){    int old=fa[x],oldf=fa[old],which=get(x);    ch[old][which]=ch[x][which^1];fa[ch[x][which^1]]=old;    ch[x][which^1]=old;fa[old]=x;fa[x]=oldf;    if (oldf)ch[oldf][ch[oldf][1]==old]=x;    updata(old);updata(x);}inline void splay(int x,int tar){    for (int old;(old=fa[x])!=tar;rotate(x))    if (fa[old]!=tar)rotate(get(old)==get(x)?old:x);    if (!tar)root=x;}inline int insert(int x){    if (!root){root=++sz;ch[sz][0]=ch[sz][1]=fa[sz]=0;size[sz]=1;key[sz]=x;return sz;}    int now=root,old=0;     while(1)    {        old=now;        now=ch[now][x>key[now]];        if (!now)        {            fa[++sz]=old;            ch[sz][0]=ch[sz][1]=0;            ch[old][x>key[old]]=sz;            size[sz]=1;            key[sz]=x;            splay(sz,0);            break;        }    }    return sz;}inline int pre(){    int now=ch[root][0];    while(ch[now][1])now=ch[now][1];    return now;}inline void del(int x){    splay(x,0);    if (!ch[root][0]&&!ch[root][1]){clear(root);root=0;return;}    if (!ch[root][1]){int oldroot=root;root=ch[root][1];fa[root]=0;clear(oldroot);return;}    if (!ch[root][0]){int oldroot=root;root=ch[root][0];fa[root]=0;clear(oldroot);return;}    int leftbig=pre(),oldroot=root;    splay(leftbig,0);    ch[root=leftbig][1]=ch[oldroot][1];    fa[ch[oldroot][1]]=root;    clear(oldroot);}inline int findnth(int x){    int now=root;    while(1)    {        if (ch[now][1]&&size[ch[now][1]]>=x)now=ch[now][1];        else         {            int temp=1;            temp+=ch[now][1]?size[ch[now][1]]:0;            if (x<=temp){splay(now,0);return now;}             now=ch[now][0];            x-=temp;        }    }}inline void print(int now){    if (ch[now][1])print(ch[now][1]);    ed--;    string s=ys[now];    int len=s.length();    for (int i=0;i<len;++i)    putchar(s[i]);if (ed) printf(" ");    if (ch[now][0])print(ch[now][0]);}inline void dfs(int now){    for (int now=1;now<=sz;++now)    cout<<now<<' '<<ys[now]<<' '<<fa[now]<<' '<<size[now]<<' '<<ch[now][0]<<' '<<ch[now][1]<<' '<<key[now]<<endl;}inline void solve(int x){    int l=x;    int r=min(x+9,tot)+2;    int aa=findnth(l);    int bb=findnth(r);    splay(bb,0);    splay(aa,bb);    ed=size[ch[ch[root][1]][0]];    print(ch[ch[root][1]][0]);    printf("\n");}int main(){//    freopen("std.in","r",stdin);//   freopen("std.out","w",stdout);    tot=0;    register int val;    hs.clear();ys.clear();    scanf("%d",&n);    insert(-inf);    insert(inf);    for (int i=1;i<=n;++i)    {        char c;        while(c=getchar(),c!='+'&&c!='?');        if (c=='+')        {            name="";            char cc;            while(1)            {                cc=getchar();                if (cc>'Z'||cc<'A')break;                name+=cc;            }            scanf("%d",&val);            if (hs[name]==0)            {                insert(val);                score[sz]=val;                hs[name]=sz;                ys[sz]=name;                ++tot;            }            else             {                int id=hs[name];                del(id);                score[id]=0;                id=insert(val);                score[hs[name]=id]=val;                ys[id]=name;           }        }        else         {            val=0;            char cc=getchar();            if (cc>='0'&&cc<='9')            {                val=cc-'0';                while(cc=getchar(),cc>='0'&&cc<='9')val=(val<<3)+(val<<1)+cc-'0';               solve(val);            }            else             {                name="";                name+=cc;                while(1)                {                        cc=getchar();                    if (cc>'Z'||cc<'A')break;                    name+=cc;                }                int id=hs[name];                splay(id,0);                printf("%d\n",size[ch[id][1]]);            }        }    }}
0 0
原创粉丝点击