• QTREE5


    题意翻译

    你被给定一棵n个点的树,点从1到n编号。每个点可能有两种颜色:黑或白。我们定义dist(a,b)为点a至点b路径上的边个数。

    一开始所有的点都是黑色的。

    要求作以下操作:

    0 i 将点i的颜色反转(黑变白,白变黑)

    1 v 询问dist(u,v)的最小值。u点必须为白色(u与v可以相同),显然如果v是白点,查询得到的值一定是0。

    特别地,如果作'1'操作时树上没有白点,输出-1。

    题解

    是QTREE4的弱化版诶……

    具体的思路可以看看Qtree4的->这里

    注意把求最大改成求最小,还有只需要到点的最短距离,不需要维护子树里的答案了

    然后查询的时候本来打算makeroot的……后来发现太麻烦了……直接access+splay,然后查询rmx即可(因为已经在这个splay里深度最大了)

      1 //minamoto
      2 #include<bits/stdc++.h>
      3 #define inf 0x3f3f3f3f
      4 using namespace std;
      5 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
      6 char buf[1<<21],*p1=buf,*p2=buf;
      7 inline int read(){
      8     #define num ch-'0'
      9     char ch;bool flag=0;int res;
     10     while(!isdigit(ch=getc()))
     11     (ch=='-')&&(flag=true);
     12     for(res=num;isdigit(ch=getc());res=res*10+num);
     13     (flag)&&(res=-res);
     14     #undef num
     15     return res;
     16 }
     17 char obuf[1<<24],*o=obuf;
     18 inline void print(int x){
     19     if(x>9) print(x/10);
     20     *o++=x%10+48;
     21 }
     22 const int N=100005;
     23 int ver[N<<1],head[N],Next[N<<1];
     24 int rev[N],fa[N],ch[N][2],w[N],col[N],lmn[N],rmn[N],len[N],val[N];
     25 multiset<int> s[N];
     26 int n,q,white=0,tot;
     27 #define ls ch[x][0]
     28 #define rs ch[x][1]
     29 inline int fir(multiset<int> &s){return s.size()?*s.begin():inf;}
     30 inline int min(int x,int y,int z){return min(x,min(y,z));}
     31 inline bool add(int u,int v){ver[++tot]=v,Next[tot]=head[u],head[u]=tot;}
     32 inline bool isroot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
     33 inline void init(){for(int i=0;i<=n;++i) lmn[i]=rmn[i]=w[i]=inf;}
     34 inline void pushr(int x){
     35     rev[x]^=1,swap(ls,rs),swap(lmn[x],rmn[x]);
     36 }
     37 inline void pushup(int x){
     38     if(!x) return;
     39     len[x]=len[ls]+len[rs]+val[x];
     40     lmn[x]=min(lmn[ls],len[ls]+val[x]+min(w[x],fir(s[x]),lmn[rs]));
     41     rmn[x]=min(rmn[rs],len[rs]+min(w[x],fir(s[x]),rmn[ls]+val[x]));
     42 }
     43 inline void pushdown(int x){
     44     if(x&&rev[x]){
     45         pushr(ls),pushr(rs),rev[x]=0;
     46     }
     47 }
     48 void rotate(int x){
     49     int y=fa[x],z=fa[y],d=ch[y][1]==x;
     50     if(!isroot(y)) ch[z][ch[z][1]==y]=x;
     51     fa[x]=z,fa[y]=x,fa[ch[x][d^1]]=y,ch[y][d]=ch[x][d^1],ch[x][d^1]=y,pushup(y);
     52 }
     53 void down(int x){
     54     if(!isroot(x)) down(fa[x]);
     55     pushdown(x);
     56 }
     57 void splay(int x){
     58     down(x);
     59     for(int y=fa[x],z=fa[y];!isroot(x);y=fa[x],z=fa[y]){
     60         if(!isroot(y))
     61         ((ch[z][1]==y)^(ch[y][1]==x))?rotate(x):rotate(y);
     62         rotate(x);
     63     }
     64     pushup(x);
     65 }
     66 void access(int x){
     67     for(int y=0;x;x=fa[y=x]){
     68         splay(x);
     69         if(rs) s[x].insert(lmn[rs]);
     70         if(y) s[x].erase(s[x].find(lmn[y]));
     71         rs=y,pushup(x);
     72     }
     73 }
     74 void modify(int x){
     75     access(x),splay(x);
     76     col[x]^=1,w[x]=col[x]?0:inf;
     77     col[x]?(++white):(--white);
     78     pushup(x);
     79 }
     80 int query(int x){
     81     access(x),splay(x);
     82     return rmn[x];
     83 }
     84 void dfs(int u){
     85     for(int i=head[u];i;i=Next[i]){
     86         int v=ver[i];
     87         if(v==fa[u]) continue;
     88         fa[v]=u,val[v]=1,dfs(v);
     89         s[u].insert(lmn[v]);
     90     }
     91     pushup(u);
     92 }
     93 int main(){
     94     //freopen("testdata.in","r",stdin);
     95     n=read();init();
     96     for(int i=1;i<n;++i){
     97         int u=read(),v=read();
     98         add(u,v),add(v,u);
     99     }
    100     dfs(1);q=read();
    101     while(q--){
    102         int op=read(),x=read();
    103         if(op){
    104             if(!white) *o++='-',*o++='1';
    105             else if(col[x]) *o++='0';
    106             else print(query(x));
    107             *o++='
    ';
    108         }
    109         
    110         else modify(x);
    111     }
    112     fwrite(obuf,o-obuf,1,stdout);
    113     return 0;
    114 }
  • 相关阅读:
    华为2016校园招聘上机笔试题
    android SQLite 使用
    handler
    fragment 给 activity 传数据
    activity 给 fragment 传递数据
    fragment (动态加载)
    fragment (静态)
    Java学习随笔之磨刀篇——环境搭建+问候世界
    Go语言设计哲学
    Ubuntu设置护眼程序
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9428573.html
Copyright © 2020-2023  润新知