• 2733: [HNOI2012]永无乡


    Description

    永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示。某些岛之间由巨大的桥连接,通过桥可以从一个岛 到达另一个岛。如果从岛 a 出发经过若干座(含 0 座)桥可以到达岛 b,则称岛 a 和岛 b 是连 通的。现在有两种操作:B x y 表示在岛 x 与岛 y 之间修建一座新桥。Q x k 表示询问当前与岛 x连通的所有岛中第 k 重要的是哪座岛,即所有与岛 x 连通的岛中重要度排名第 k 小的岛是哪 座,请你输出那个岛的编号。
     
    Input

    输入文件第一行是用空格隔开的两个正整数 n 和 m,分别 表示岛的个数以及一开始存在的桥数。接下来的一行是用空格隔开的 n 个数,依次描述从岛 1 到岛 n 的重要度排名。随后的 m 行每行是用空格隔开的两个正整数 ai 和 bi,表示一开始就存 在一座连接岛 ai 和岛 bi 的桥。后面剩下的部分描述操作,该部分的第一行是一个正整数 q, 表示一共有 q 个操作,接下来的 q 行依次描述每个操作,操作的格式如上所述,以大写字母 Q 或B 开始,后面跟两个不超过 n 的正整数,字母与数字以及两个数字之间用空格隔开。 对于 20%的数据 n≤1000,q≤1000
     
    对于 100%的数据 n≤100000,m≤n,q≤300000
     
    Output

    对于每个 Q x k 操作都要依次输出一行,其中包含一个整数,表 示所询问岛屿的编号。如果该岛屿不存在,则输出-1。
     
    Sample Input
    5 1
    4 3 2 5 1
    1 2
    7
    Q 3 2
    Q 2 1
    B 2 3
    B 1 5
    Q 2 1
    Q 2 4
    Q 2 3
    Sample Output
    -1
    2
    5
    1
    2

    平衡树启发式合并

    每次合并都把小的拆开,放到大的里面(听说数据很水,随机的,不旋转就可以过,写了一个,然后就pascal的rank1了)

    还是正常一点写一个splay吧(不过常数有点大,所以是深度超过32才splay)

      1 const
      2         maxn=100010;
      3         dep=32;
      4 type
      5         node=record
      6           son:array[0..1]of longint;
      7           size,data,fa:longint;
      8         end;
      9 var
     10         tree:array[0..maxn]of node;
     11         f,root:array[0..maxn]of longint;
     12         n,m,q:longint;
     13  
     14 function find(x:longint):longint;
     15 begin
     16         if f[x]=x then exit(x);
     17         f[x]:=find(f[x]);
     18         exit(f[x]);
     19 end;
     20  
     21 procedure rotate(x,w:longint;var root:longint);
     22 var
     23     y:longint;
     24 begin
     25     y:=tree[x].fa;
     26     tree[y].son[w]:=tree[x].son[w xor 1];
     27     if tree[x].son[w xor 1]<>0 then tree[tree[x].son[w xor 1]].fa:=y;
     28     tree[x].son[w xor 1]:=y;
     29     if y=root then root:=x
     30     else
     31       if tree[tree[y].fa].son[0]=y then tree[tree[y].fa].son[0]:=x
     32       else tree[tree[y].fa].son[1]:=x;
     33     tree[x].fa:=tree[y].fa;
     34     tree[y].fa:=x;
     35     tree[y].size:=tree[tree[y].son[0]].size+tree[tree[y].son[1]].size+1;
     36 end;
     37  
     38 procedure splay(x:longint;var root:longint);
     39 var
     40     y:longint;
     41 begin
     42     while root<>x do
     43       begin
     44         y:=tree[x].fa;
     45         if y=root then
     46           if tree[y].son[0]=x then rotate(x,0,root)
     47           else rotate(x,1,root)
     48         else
     49           if tree[tree[y].fa].son[0]=y then
     50             if tree[y].son[0]=x then
     51               begin
     52                 rotate(y,0,root);
     53                 rotate(x,0,root);
     54               end
     55             else
     56               begin
     57                 rotate(x,1,root);
     58                 rotate(x,0,root);
     59               end
     60           else
     61             if tree[y].son[0]=x then
     62               begin
     63                 rotate(x,0,root);
     64                 rotate(x,1,root);
     65               end
     66             else
     67               begin
     68                 rotate(y,1,root);
     69                 rotate(x,1,root);
     70               end;
     71       end;
     72     tree[x].size:=tree[tree[x].son[0]].size+tree[tree[x].son[1]].size+1;
     73 end;
     74  
     75 procedure insert(x:longint;var root:longint);
     76 var
     77     now,step:longint;
     78 begin
     79         now:=root;
     80         step:=0;
     81         while true do
     82           begin
     83             inc(step);
     84             inc(tree[now].size);
     85             if tree[x].data<tree[now].data then
     86               if tree[now].son[0]=0 then break
     87               else now:=tree[now].son[0]
     88             else
     89               if tree[now].son[1]=0 then break
     90               else now:=tree[now].son[1];
     91           end;
     92         if tree[x].data<tree[now].data then tree[now].son[0]:=x
     93         else tree[now].son[1]:=x;
     94         tree[x].size:=1;
     95         tree[x].son[0]:=0;
     96         tree[x].son[1]:=0;
     97         tree[x].fa:=now;
     98         if step>dep then splay(x,root);
     99 end;
    100  
    101 procedure dfs(x:longint;var root:longint);
    102 begin
    103         with tree[x] do
    104           begin
    105             if son[0]<>0 then dfs(son[0],root);
    106             if son[1]<>0 then dfs(son[1],root);
    107             insert(x,root);
    108           end;
    109 end;
    110  
    111 procedure union(x,y:longint);
    112 var
    113         u,v:longint;
    114 begin
    115         u:=find(x);
    116         v:=find(y);
    117         if u=v then exit;
    118         if tree[root[u]].size<tree[root[v]].size then
    119           begin
    120             dfs(root[u],root[v]);
    121             f[u]:=v;
    122           end
    123         else
    124           begin
    125             dfs(root[v],root[u]);
    126             f[v]:=u;
    127           end;
    128 end;
    129  
    130 procedure init;
    131 var
    132         i,x,y:longint;
    133 begin
    134         read(n,m);
    135         for i:=1 to n do
    136           begin
    137             f[i]:=i;
    138             root[i]:=i;
    139             tree[i].size:=1;
    140           end;
    141         for i:=1 to n do
    142           read(tree[i].data);
    143         for i:=1 to m do
    144           begin
    145             read(x,y);
    146             union(x,y);
    147           end;
    148 end;
    149  
    150 function ans(k:longint;var root:longint):longint;
    151 var
    152     now,step:longint;
    153 begin
    154         now:=root;
    155         step:=0;
    156         if k>tree[now].size then exit(-1);
    157         while true do
    158           begin
    159             inc(step);
    160             if k=tree[tree[now].son[0]].size+1 then
    161             begin
    162               if step>dep then splay(now,root);
    163               exit(now);
    164             end;
    165             if k<=tree[tree[now].son[0]].size then now:=tree[now].son[0]
    166             else
    167               begin
    168                 dec(k,tree[tree[now].son[0]].size+1);
    169                 now:=tree[now].son[1];
    170               end;
    171           end;
    172 end;
    173  
    174 procedure work;
    175 var
    176         i,x,y:longint;
    177         c:char;
    178 begin
    179         readln(q);
    180         for i:=1 to q do
    181           begin
    182             readln(c,x,y);
    183             if c='Q' then
    184               begin
    185                 if (x>n) or (x<1) then writeln(-1)
    186                 else writeln(ans(y,root[find(x)]));
    187               end
    188             else union(x,y);
    189           end;
    190 end;
    191  
    192 begin
    193         init;
    194         work;
    195 end.
    View Code
  • 相关阅读:
    Git连接Github
    全民来打飞机~~(设计探讨)
    mongo学习
    redis aop持久化
    redis的超时删除策略
    redis 学习,没事的时候看看增长知识面
    MySQL query / clause execution order
    用redis做超时判断 感觉写的很有意思
    python 编码问题(转载)
    git 个人学习
  • 原文地址:https://www.cnblogs.com/Randolph87/p/3677270.html
Copyright © 2020-2023  润新知