• Hash_bzoj1862: [Zjoi2006]GameZ游戏排名系统


      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cmath>
      5 #include <algorithm>
      6 using namespace std;
      7 #define maxn 400005
      8 #define p1 63
      9 #define p2 103
     10 #define mod1 1000007
     11 #define mod2 2000007
     12 int n,tot,len,need,fact,fa[maxn],son[maxn][2],val[maxn],size[maxn];
     13 char Name[maxn][20],name[20];
     14 void read(int &x){
     15     x=0; int f=1; char ch;
     16     for (ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') f=-1;
     17     for (;isdigit(ch);ch=getchar()) x=x*10+ch-'0'; x*=f;
     18 }
     19 struct S{
     20     int root;
     21     void prepare(){root=0,memset(son,0,sizeof(son));}
     22     int which(int x){
     23         return son[fa[x]][1]==x;
     24     }
     25     void updata(int x){
     26         size[x]=1;
     27         if (son[x][0]) size[x]+=size[son[x][0]];
     28         if (son[x][1]) size[x]+=size[son[x][1]];
     29     }
     30     void rotata(int x){
     31         int y=fa[x],d=which(x),dd=which(y);
     32         if (fa[y]) son[fa[y]][dd]=x; fa[x]=fa[y];
     33         fa[son[x][d^1]]=y,son[y][d]=son[x][d^1];
     34         fa[y]=x,son[x][d^1]=y,updata(y);
     35     }
     36     void splay(int x,int goal){
     37         while (fa[x]!=goal){
     38             if (fa[fa[x]]==goal) rotata(x);
     39             else if (which(x)==which(fa[x])) rotata(fa[x]),rotata(x);
     40             else rotata(x),rotata(x);
     41         }
     42         updata(x); if (goal==0) root=x;
     43     }
     44     void insert(int x){
     45         int y=root; bool bo;
     46         if (root==0){
     47             root=x; updata(x);
     48             return;
     49         }
     50         for (;;){
     51             bo=0;
     52             if (val[x]<=val[y]){
     53                 if (!son[y][0]) son[y][0]=x,fa[x]=y,updata(x),updata(y),bo=1,splay(x,0);
     54                 else y=son[y][0];
     55             }else{
     56                 if (son[y][1]==0) son[y][1]=x,fa[x]=y,updata(x),updata(y),bo=1,splay(x,0);
     57                 else y=son[y][1];
     58             }
     59             if (bo==1) break;
     60         }
     61     }
     62     int prep(int x){
     63         splay(x,0);
     64         int y=son[x][0];
     65         while (son[y][1]) y=son[y][1];
     66         return y;
     67     }
     68     void Delete(int x){
     69         int y=prep(x),z;
     70         if (y==0){
     71             splay(x,0); z=son[x][1];
     72             root=z,son[x][0]=son[x][1]=fa[x]=size[x]=fa[z]=0;
     73         }else{
     74             splay(y,0),splay(x,y); z=son[x][1];
     75             fa[z]=y,son[y][1]=z,updata(y);
     76             fa[x]=son[x][0]=son[x][1]=size[x]=0;
     77         }
     78     }
     79     int rank(int x){
     80         splay(x,0);
     81         return size[son[x][0]]+1;
     82     }
     83     int kth(int x){
     84         int y=root; bool bo;
     85         for (;;){
     86             if (size[son[y][0]]+1==x) return y;
     87             else if (size[son[y][0]]>=x) y=son[y][0];
     88             else x-=size[son[y][0]]+1,y=son[y][1];
     89         }
     90     }
     91     void print(int x){
     92         if (son[x][1]) print(son[x][1]);
     93         fact++;
     94         for (int i=1;i<=Name[x][0];i++) printf("%c",Name[x][i]);
     95         if (fact<need) printf(" ");
     96         if (son[x][0]) print(son[x][0]);
     97     }
     98     void query(int u,int v){
     99         int x=kth(u-1),y=kth(v+1),z; fact=0;
    100         splay(x,0),splay(y,x); z=son[y][0];
    101         print(z); puts("");
    102     }
    103 }Splay;
    104 struct hash{
    105     int now[mod1+1],prep[maxn],Ha[maxn][2];
    106     int ha1(){
    107         int x=0;
    108         for (int i=1;i<len;i++){
    109             x=(x+(int)name[i])%mod1*p1%mod1;
    110         }
    111         return x;
    112     }
    113     int ha2(){
    114         int x=0;
    115         for (int i=1;i<len;i++){
    116             x=(x+(int)name[i])%mod2*p2%mod2;
    117         }
    118         return x;
    119     }
    120     bool exist(){
    121         int x1=ha1(),x2=ha2(); bool bo=0;
    122         for (int i=now[x1];i;i=prep[i]){
    123             if (Ha[i][0]==x2){
    124                 bo=1; break;
    125             }
    126         }
    127         return bo;
    128     }
    129     int number(){
    130         int x1=ha1(),x2=ha2();
    131         for (int i=now[x1];i;i=prep[i]){
    132             if (Ha[i][0]==x2) return Ha[i][1];
    133         }
    134     }
    135     void insert(){
    136         int x1=ha1(),x2=ha2();
    137         prep[++tot]=now[x1],now[x1]=tot;
    138         Ha[tot][0]=x2,Ha[tot][1]=tot;
    139         for (int i=1;i<len;i++) Name[tot][0]++,Name[tot][Name[tot][0]]=name[i];
    140     }
    141 }Hash;
    142 int main(){
    143     char op[20];
    144     memset(size,0,sizeof(size));
    145     read(n),tot=0; Splay.prepare();
    146     val[n+1]=-1,val[n+2]=2147483647;
    147     Splay.insert(n+1),Splay.insert(n+2);
    148     for (int w,u,i=1;i<=n;i++){
    149         scanf("%s",op+1);
    150         if (op[1]=='+'){
    151             len=strlen(op+1); read(w);
    152             for (int j=2;j<=len;j++) name[j-1]=op[j];
    153             if (!Hash.exist()) Hash.insert(),u=Hash.number(),val[u]=w,Splay.insert(u);
    154             else{
    155                 u=Hash.number();
    156                 Splay.Delete(u),val[u]=w,Splay.insert(u);
    157             }
    158         }else if (op[1]=='?'&&!isdigit(op[2])){
    159             len=strlen(op+1);
    160             for (int j=2;j<=len;j++) name[j-1]=op[j];
    161             w=Hash.number();
    162             printf("%d
    ",tot-Splay.rank(w)+2);
    163         }else{
    164             len=strlen(op+1); w=0;
    165             for (int j=2;j<=len;j++) w=w*10+op[j]-'0';
    166             w=tot-w+1;
    167             u=max(1,w-10+1); need=w-u+1;
    168             Splay.query(u+1,w+1);
    169         }
    170     }
    171     return 0;
    172 }
    View Code

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1862

    题意参照题面。

    做法:Splay+Hash。

    裸的splay,支持插入删除查询排名即可,为什么要用Hash呢,因为如果某玩家上传过记录就得把之前的记录清空,所以我们需要用字符串Hash来判重,字符串我们使用双hash值,一个用来确定地址,第一个来作为val,这样就能降低在哈希表中查找的复杂度,再记录该玩家在Splay树中的标号即可。

    splay+Hash。

  • 相关阅读:
    js之判断非空
    解决eclipse添加不了tomcat8的问题
    Java(eclipse)连接MySQL8.0以上版本数据库方式
    面试必备的:Redis和MongoDB的区别
    简述关系型数据库和非关系型数据库
    非关系型数据库MongoDB初探,以及和Redis的对比
    day53:django:URL别名/反向解析&URL分发&命名空间&ORM多表操作修改/查询
    day52:django:ORM单表/多表操作
    day51:django:dispatch&模板渲染&过滤器&标签&组件&静态文件配置
    day50:django:有名/无名分组&FBV/CBV
  • 原文地址:https://www.cnblogs.com/OYzx/p/5635351.html
Copyright © 2020-2023  润新知