zoukankan      html  css  js  c++  java
  • 洛谷P4116 Qtree3

    题目描述

    给出(N)个点的一棵树((N-1)条边),节点有白有黑,初始全为白

    有两种操作:

    (0) (i) : 改变某点的颜色(原来是黑的变白,原来是白的变黑)

    (1) (v) : 询问(1)(v)的路径上的第一个黑点,若无,输出(-1)

    输入输出格式

    输入格式:

    第一行 (N)(Q),表示(N)个点和(Q)个操作

    第二行到第(N)(N-1)条无向边

    再之后(Q)行,每行一个操作"(0) (i)" 或者"(1) (v)" ((1 ≤ i, v ≤ N)).

    输出格式:

    对每个(1) (v)操作输出结果

    输入输出样例

    输入样例#1:

    9 8
    1 2
    1 3
    2 4
    2 9
    5 9
    7 9
    8 9
    6 8
    1 3
    0 8
    1 6
    1 7
    0 2
    1 9
    0 2
    1 9 
    

    输出样例#1:

    -1
    8
    -1
    2
    -1
    

    说明

    For (1/3) of the test cases, (N=5000, Q=400000).

    For (1/3) of the test cases, (N=10000, Q=300000).

    For (1/3) of the test cases, (N=100000, Q=100000).

    思路:对于操作(1),显然我们可以利用线段树的单点修改操作来实现,对于操作(2),要求求(1)(v)的路径上的第一个黑点,那么我们可以考虑维护两点之间路径之间是黑点的点的深度最浅值,可以用树链剖分+线段树来实现。

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<cctype>
    #define maxn 100007
    #define ls rt<<1
    #define rs rt<<1|1
    using namespace std;
    const int inf=1e9+7;
    int n,m,num,top[maxn],cnt,head[maxn],d[maxn],size[maxn],id[maxn];
    int minn[maxn<<2],fa[maxn],son[maxn],a[maxn],w[maxn];
    inline int qread() {
      char c=getchar();int num=0,f=1;
      for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
      for(;isdigit(c);c=getchar()) num=num*10+c-'0';
      return num*f;
    }
    struct node {
      int v,nxt;
    }e[maxn<<1];
    inline void ct(int u, int v) {
      e[++num].v=v;
      e[num].nxt=head[u];
      head[u]=num;
    }
    void dfs1(int u) {
      size[u]=1;
      for(int i=head[u];i;i=e[i].nxt) {
      	int v=e[i].v;
      	if(v!=fa[u]) {
      	  d[v]=d[u]+1;
      	  fa[v]=u;
      	  dfs1(v);
      	  size[u]+=size[v];
      	  if(size[v]>size[son[u]]) son[u]=v;
    	}
      }
    }
    void dfs2(int u, int t) {
      id[u]=++cnt;
      top[u]=t;
      a[cnt]=u;
      if(son[u]) dfs2(son[u],t);
      for(int i=head[u];i;i=e[i].nxt) {
      	int v=e[i].v;
      	if(v!=fa[u]&&v!=son[u]) dfs2(v,v);
      }
    }
    inline void pushup(int rt) {
      minn[rt]=min(minn[ls],minn[rs]);
    }
    void build(int rt, int l, int r) {
      if(l==r) {
      	minn[rt]=inf;
      	return;
      }
      int mid=(l+r)>>1;
      build(ls,l,mid);
      build(rs,mid+1,r);
      pushup(rt);
    }
    void modify(int rt, int l, int r, int L) {
      if(l==r) {
      	if(w[id[L]]^=1) minn[rt]=l;
      	else minn[rt]=inf;
      	return;
      }
      int mid=(l+r)>>1;
      if(L<=mid) modify(ls,l,mid,L);
      else modify(rs,mid+1,r,L);
      pushup(rt);
    }
    int cmin(int rt, int l, int r, int L, int R) {
      if(L>r||R<l) return inf;
      if(L<=l&&r<=R) return minn[rt];
      int mid=(l+r)>>1,ans=inf;
      if(L<=mid) ans=min(ans,cmin(ls,l,mid,L,R));
      if(R>mid) ans=min(ans,cmin(rs,mid+1,r,L,R));
      return ans;
    }
    int query(int x, int y) {
      int fx=top[x],fy=top[y],ans=inf;
      while(fx!=fy) {
      	if(d[fx]<d[fy]) swap(x,y),swap(fx,fy);
      	ans=min(ans,cmin(1,1,cnt,id[fx],id[x]));
      	x=fa[fx],fx=top[x];
      }
      if(id[x]>id[y]) swap(x,y);
      ans=min(ans,cmin(1,1,cnt,id[x],id[y]));
      return ans;
    }
    int main() {
      n=qread(),m=qread();
      for(int i=1,u,v;i<n;++i) {
      	u=qread(),v=qread();
      	ct(u,v);ct(v,u);
      }
      dfs1(1);dfs2(1,1);build(1,1,n);
      for(int i=1,k,x;i<=m;++i) {
      	k=qread(),x=qread();
      	if(!k) modify(1,1,n,id[x]);
      	else {
      	  int zrj=query(1,x);
    	  if(zrj==inf) printf("-1
    ");
    	  else printf("%d
    ",a[zrj]);
    	}
      }
      return 0;
    }
    
  • 相关阅读:
    Windows 科研软件推荐
    有关Python 包 (package) 的基本知识
    《Using Python to Access Web Data》Week4 Programs that Surf the Web 课堂笔记
    Coursera助学金申请模板
    《Using Databases with Python》 Week2 Basic Structured Query Language 课堂笔记
    Jupyter 解决单个变量输出问题
    解决 pandas 中打印 DataFrame 行列显示不全的问题
    《Using Python to Access Web Data》 Week3 Networks and Sockets 课堂笔记
    缓存击穿及解决方案
    jvm垃圾收集器
  • 原文地址:https://www.cnblogs.com/grcyh/p/10201460.html
Copyright © 2011-2022 走看看