• [bzoj3991] [SDOI2015]寻宝游戏


      显然每次走过的最小路程,就是按照dfs序走的总路程。

      如果没修改的话其实是虚树。。

      既然带了修改。。。其实就是维护关键点的dfs序。

      用棵平衡树维护一下就好了,涉及到插入、删除、查找前驱后继、查找最大最小值。

      算两点间路程还得求lca

      (所以这题就变成treap全套板子了。。。

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<algorithm>
      5 #define ll long long
      6 using namespace std;
      7 const int maxn=100233;
      8 struct zs{int too,pre,dis;}e[maxn<<1];int tot,last[maxn];
      9 int lc[maxn<<1],rc[maxn<<1],p[maxn<<1],rnd[maxn<<1],tt,V,rt,PRE,AFT,st,ed;
     10 int dep[maxn],bel[maxn],fa[maxn],sz[maxn],dfn[maxn],tim;
     11 ll dis[maxn],ans;
     12 int i,j,k,n,m,cnt;
     13 bool is[maxn];
     14  
     15 int ra,fh;char rx;
     16 inline int read(){
     17     rx=getchar(),ra=0,fh=1;
     18     while((rx<'0'||rx>'9')&&rx!='-')rx=getchar();
     19     if(rx=='-')fh=-1,rx=getchar();
     20     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra*fh;
     21 }
     22  
     23 inline void lturn(int &x){int R=rc[x];rc[x]=lc[R],lc[R]=x,x=R;}
     24 inline void rturn(int &x){int L=lc[x];lc[x]=rc[L],rc[L]=x,x=L;}
     25 void insert(int &x){
     26     if(!x){x=++tt,p[x]=V,rnd[x]=rand()+tt;return;}
     27     if(dfn[V]<dfn[p[x]]){
     28         insert(lc[x]);
     29         if(rnd[lc[x]]<rnd[x])rturn(x);
     30     }else{
     31         insert(rc[x]);
     32         if(rnd[rc[x]]<rnd[x])lturn(x);
     33     }
     34 }
     35 void del(int &x){
     36     if(p[x]==V){
     37         if(!lc[x]||!rc[x])x=lc[x]|rc[x];
     38         else if(rnd[lc[x]]<rnd[rc[x]])rturn(x),del(x);
     39         else lturn(x),del(x);
     40     }else
     41     if(dfn[V]<dfn[p[x]])del(lc[x]);else del(rc[x]);
     42 }
     43 void getpre(int x){
     44     if(!x)return;
     45     if(dfn[p[x]]<dfn[V])PRE=p[x],getpre(rc[x]);
     46     else getpre(lc[x]);
     47 }
     48 void getaft(int x){
     49     if(!x)return;
     50     if(dfn[p[x]]>dfn[V])AFT=p[x],getaft(lc[x]);
     51     else getaft(rc[x]);
     52 }
     53 inline void getst(){
     54     int x=rt;
     55     while(lc[x])x=lc[x];
     56     st=p[x];
     57 }
     58 inline void geted(){
     59     int x=rt;
     60     while(rc[x])x=rc[x];
     61     ed=p[x];
     62 }
     63  
     64  
     65 void dfs(int x){
     66     sz[x]=1,dep[x]=dep[fa[x]]+1;
     67     for(int i=last[x];i;i=e[i].pre)if(e[i].too!=fa[x])
     68         fa[e[i].too]=x,dis[e[i].too]=dis[x]+e[i].dis,dfs(e[i].too),sz[x]+=sz[e[i].too];
     69 }
     70 void dfs2(int x,int chain){
     71     int mx=0,i;dfn[x]=++tim,bel[x]=chain;
     72     for(i=last[x];i;i=e[i].pre)if(e[i].too!=fa[x]&&sz[e[i].too]>sz[mx])mx=e[i].too;
     73     if(!mx)return;
     74     dfs2(mx,chain);
     75     for(i=last[x];i;i=e[i].pre)if(e[i].too!=fa[x]&&e[i].too!=mx)dfs2(e[i].too,e[i].too);
     76 }
     77 inline int getlca(int a,int b){
     78     while(bel[a]!=bel[b]){
     79         if(dep[bel[a]]<dep[bel[b]])swap(a,b);
     80         a=fa[bel[a]];
     81     }
     82     return dep[a]<dep[b]?a:b;
     83 }
     84 inline ll getdis(int a,int b){
     85     int c=getlca(a,b);
     86     return dis[b]-dis[c]+dis[a]-dis[c];
     87 }
     88 inline void insert(int a,int b,int c){
     89     e[++tot].too=b,e[tot].dis=c,e[tot].pre=last[a],last[a]=tot,
     90     e[++tot].too=a,e[tot].dis=c,e[tot].pre=last[b],last[b]=tot;
     91 }
     92 int main(){
     93     n=read(),m=read();
     94     for(i=1;i<n;i++)j=read(),k=read(),insert(j,k,read());
     95     dfs(1),dfs2(1,1);
     96     while(m--){
     97         i=read();
     98         if(!is[i]){
     99             V=i,PRE=AFT=0,getpre(rt),getaft(rt);
    100             if(PRE||AFT){
    101                 if(!PRE)PRE=ed;if(!AFT)AFT=st;
    102                 ans=ans-getdis(PRE,AFT)+getdis(PRE,i)+getdis(i,AFT);
    103             }
    104             insert(rt),is[i]=1,cnt++;
    105         }else{
    106             V=i,PRE=AFT=0,getpre(rt),getaft(rt);
    107             if(PRE||AFT){
    108                 if(!PRE)PRE=ed;if(!AFT)AFT=st;
    109                 ans=ans+getdis(PRE,AFT)-getdis(PRE,i)-getdis(i,AFT);
    110             }
    111             del(rt),is[i]=0,cnt--;
    112         }
    113         if(cnt)getst(),geted();
    114         printf("%lld
    ",ans);
    115     }
    116     return 0;
    117 }
    View Code
  • 相关阅读:
    pycharm 中查找替换功能
    Python中括号的区别及用途
    python:return
    WAMPSERVER 启动不了APACHE原因
    Python为什么如此不同?
    Python初试云雨情
    mariadb 的日志
    MySql 之UUID()
    python 自建爬虫复用简单框架(gevent异步)
    python分布式进程
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5596279.html
Copyright © 2020-2023  润新知