• uoj#349 【WC2018】即时战略


    题目链接

    正解:$link-cut tree$。

    这道题我在考场上从看题到放弃只花了$20$多分钟。。

    爆刚$t2$无果,$12$点的钟声响起,我无奈地开始看这道题,然后发现了生的希望。。

    只写了二十几分钟,然后又滚回去刚$t2$了。。正解根本就没去想了(虽然本来也不会。。

    不得不说这道题的标算还是很妙的,我就算去想也不可能往$LCT$这方面想。。

    我们每次新开一个点,就直接从根结点开始$explore$。

    我们可以用$LCT$维护当前这棵树的链,于是每次从现在$splay$的根结点开始往下走。

    如果$explore$返回的点在左子树,我们就往左移,在右子树则往右移,如果不在这棵树我们就直接跳到$explore$返回的这个点所在的树。

    可以发现,在一棵$splay$上我们最多只会移动$splay$深度次数,那么时间复杂度和查询复杂度也可以保证在$O(n log n)$。

    注意一点,就是每次找到目标点以后都要通过$access$来保证复杂度,以及链的情况需要特判。

    $upd$:这个做法被$hack$了,所以我也不知道正解是什么。

      1 // RTS sample program
      2 #include <bits/stdc++.h>
      3 #include "rts.h"
      4 #define il inline
      5 #define RG register
      6 #define N (300005)
      7 
      8 using namespace std;
      9 
     10 int ch[N][2],fa[N],l[N],r[N],p[N],vis[N],lst,nxt,n;
     11 
     12 deque<int> Q;
     13 deque<int>::iterator it;
     14 
     15 il void work(){
     16   Q.push_back(p[1]);
     17   for (RG int i=2,x,v,op;i<=n;++i){
     18     if (vis[p[i]]) continue;
     19     v=explore(p[1],p[i]);
     20     if (nxt==v){
     21       op=2,it=Q.end(),x=*(--it);
     22       while (1){
     23     v=explore(x,p[i]),vis[v]=1;
     24     op==1?Q.push_front(v):Q.push_back(v);
     25     if (v==p[i]) break; x=v;
     26       }
     27     } else if (lst==v){
     28       op=1,it=Q.begin(),x=*it;
     29       while (1){
     30     v=explore(x,p[i]),vis[v]=1;
     31     op==1?Q.push_front(v):Q.push_back(v);
     32     if (v==p[i]) break; x=v;
     33       }
     34     } else{
     35       if (!lst) op=1,lst=v; else op=2,nxt=v;
     36       op==1?Q.push_front(v):Q.push_back(v);
     37       vis[v]=1; if (v==p[i]) continue; x=v;
     38       while (1){
     39     v=explore(x,p[i]),vis[v]=1;
     40     op==1?Q.push_front(v):Q.push_back(v);
     41     if (v==p[i]) break; x=v;
     42       }
     43     }
     44   }
     45   return;
     46 }
     47 
     48 il int isroot(RG int x){
     49   return ch[fa[x]][0]!=x && ch[fa[x]][1]!=x;
     50 }
     51 
     52 il void pushup(RG int x){
     53   l[x]=ch[x][0]?l[ch[x][0]]:x;
     54   r[x]=ch[x][1]?r[ch[x][1]]:x; return;
     55 }
     56 
     57 il void rotate(RG int x){
     58   RG int y=fa[x],z=fa[y],k=ch[y][0]==x;
     59   if (!isroot(y)) ch[z][ch[z][1]==y]=x;
     60   fa[x]=z,ch[y][k^1]=ch[x][k],fa[ch[x][k]]=y;
     61   ch[x][k]=y,fa[y]=x,pushup(y),pushup(x); return;
     62 }
     63 
     64 il void splay(RG int x){
     65   while (!isroot(x)){
     66     RG int y=fa[x],z=fa[y];
     67     if (!isroot(y)) rotate((ch[z][0]==y)^(ch[y][0]==x)?x:y);
     68     rotate(x);
     69   }
     70   return;
     71 }
     72 
     73 il void access(RG int x){
     74   RG int t=0;
     75   while (x){
     76     splay(x),ch[x][1]=t;
     77     pushup(x),t=x,x=fa[x];
     78   }
     79   return;
     80 }
     81 
     82 void play(int _n, int T, int dataType) {
     83   srand(19260817+3),n=_n;
     84   for (RG int i=1;i<=n;++i) p[i]=i;
     85   random_shuffle(p+2,p+n+1);
     86   if (dataType==3){ work(); return; }
     87   for (RG int i=1;i<=n;++i) l[i]=r[i]=i;
     88   for (RG int i=2,x,v;i<=n;++i){
     89     if (vis[p[i]]) continue; x=p[1];
     90     while (x!=p[i]){
     91       splay(x);
     92       while (1){
     93     v=explore(x,p[i]);
     94     if (v==r[ch[x][0]]) x=ch[x][0];
     95     else if (v==l[ch[x][1]]) x=ch[x][1];
     96     else{
     97       if (!vis[v]) vis[v]=1,fa[v]=x;
     98       x=v; break;
     99     }
    100       }
    101     }
    102     access(x);
    103   }
    104   return;
    105 }
  • 相关阅读:
    PHP危险函数总结学习
    2019网络与信息安全专项赛题解
    BUUCTF平台-web-边刷边记录-2
    SpringCloud-Config 分布式配置中心
    SpringCloud-Gateway 网关路由、断言、过滤
    SpringCloud-Ribbon负载均衡机制、手写轮询算法
    服务注册与发现-Eureka、Consul、Zookeeper的区别
    Docker 私有仓库搭建
    微服务熔断限流Hystrix之流聚合
    微服务熔断限流Hystrix之Dashboard
  • 原文地址:https://www.cnblogs.com/wfj2048/p/8443128.html
Copyright © 2020-2023  润新知