zoukankan      html  css  js  c++  java
  • SPOJ QTREE3

    You are given a tree (an acyclic undirected connected graph) with N nodes. The tree nodes are numbered from 1 to N. In the start, the color of any node in the tree is white.

    We will ask you to perfrom some instructions of the following form:

    • 0 i : change the color of the i-th node (from white to black, or from black to white);
      or
    • 1 v : ask for the id of the first black node on the path from node 1 to node v. if it doesn't exist, you may return -1 as its result.

    Input

    In the first line there are two integers N and Q.

    In the next N-1 lines describe the edges in the tree: a line with two integers a b denotes an edge between a and b.

    The next Q lines contain instructions "0 i" or "1 v" (1 ≤ i, v ≤ N).

    Output

    For each "1 v" operation, write one integer representing its result.

    Example

    Input:
    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 
    
    Output:
    -1
    8
    -1
    2
    -1
    

    Constraints & Limits

    There are 12 real input files.

    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.

    一棵树,点数<=100000,初始全是白点,支持两种操作: 
    1.将某个点的颜色反色。 
    2.询问某个点至根节点路径上第一个黑点是哪个。

    树链剖分

    注意到询问的链都是(1,v)

    在线段树上维护区间内深度最浅的黑色点位置即可,注意线段树结点到原树的反向映射

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<queue>
      6 using namespace std;
      7 const int INF=1e9;
      8 const int mxn=100010;
      9 int read(){
     10     int x=0,f=1;char ch=getchar();
     11     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     12     while(ch>='0' && ch<='9'){x=x*10-'0'+ch;ch=getchar();}
     13     return x*f;
     14 }
     15 struct edge{int v,nxt;}e[mxn<<1];
     16 int hd[mxn],mct=0;
     17 int n,q;
     18 void add_edge(int u,int v){
     19     e[++mct].v=v;e[mct].nxt=hd[u];hd[u]=mct;return;
     20 }
     21 struct node{
     22     int fa,son;
     23     int top,size;
     24     int w;
     25 }t[mxn];
     26 int sz=0;
     27 int dep[mxn];
     28 int id[mxn];
     29 void DFS1(int u,int fa){
     30     dep[u]=dep[fa]+1;
     31     t[u].size=1;
     32     for(int i=hd[u];i;i=e[i].nxt){
     33         int v=e[i].v;if(v==fa)continue;
     34         t[v].fa=u;
     35         DFS1(v,u);
     36         t[u].size+=t[v].size;
     37         if(t[v].size>t[t[u].son].size) 
     38             t[u].son=v;
     39     }
     40     return;
     41 }
     42 void DFS2(int u,int top){
     43     t[u].w=++sz;t[u].top=top;
     44     id[sz]=u;
     45     if(t[u].son)DFS2(t[u].son,top);
     46     for(int i=hd[u];i;i=e[i].nxt){
     47         int v=e[i].v;
     48         if(v==t[u].fa || v==t[u].son)continue;
     49         DFS2(v,v);
     50     }
     51     return;
     52 }
     53 struct SGT{
     54     int ps;
     55     int c;
     56 }st[mxn<<2];
     57 void Build(int l,int r,int rt){
     58     st[rt].ps=INF;
     59     if(l==r)return;
     60     int mid=(l+r)>>1;
     61     Build(l,mid,rt<<1);Build(mid+1,r,rt<<1|1);
     62     return;
     63 }
     64 void update(int p,int l,int r,int rt){
     65     if(l==r){
     66         st[rt].c^=1;
     67         st[rt].ps=(st[rt].c)?l:INF;
     68         return;
     69     }
     70     int mid=(l+r)>>1;
     71     if(p<=mid)update(p,l,mid,rt<<1);
     72     else update(p,mid+1,r,rt<<1|1);
     73     st[rt].ps=min(st[rt<<1].ps,st[rt<<1|1].ps);
     74     return;
     75 }
     76 int query(int L,int R,int l,int r,int rt){
     77     if(L<=l && r<=R){return st[rt].ps;}
     78     int mid=(l+r)>>1;
     79     int res=INF;
     80     if(L<=mid)res=min(res,query(L,R,l,mid,rt<<1));
     81     if(R>mid && res>mid)res=min(res,query(L,R,mid+1,r,rt<<1|1));
     82     return res;
     83 }
     84 int Qt(int x,int y){
     85     int res=INF;
     86     while(t[x].top!=t[y].top){
     87         if(dep[t[x].top]<dep[t[y].top])swap(x,y);
     88         res=min(res,query(t[t[x].top].w,t[x].w,1,n,1));
     89         x=t[t[x].top].fa;
     90     }
     91     if(dep[x]>dep[y])swap(x,y);
     92     res=min(res,query(t[x].w,t[y].w,1,n,1));
     93     return res;
     94 }
     95 int main(){
     96     int i,j,u,v;
     97     n=read();q=read();
     98     for(i=1;i<n;i++){
     99         u=read();v=read();
    100         add_edge(u,v);
    101         add_edge(v,u);
    102     }
    103     DFS1(1,0);
    104     DFS2(1,1);
    105     Build(1,n,1);
    106     while(q--){
    107         u=read();v=read();
    108         if(!u)
    109             update(t[v].w,1,n,1);
    110         else{
    111             int ans=Qt(1,v);
    112             if(ans>=INF){printf("-1
    ");continue;}
    113             ans=id[ans];
    114             printf("%d
    ",ans);
    115         }
    116     }
    117     return 0;
    118 }
  • 相关阅读:
    Win10 安装GNU 编译器(gcc、g++ 和 gfortran)
    三维地图制作 数据选型 相关参考资料
    借助mapshaper的简化来修复geojson的拓扑错误
    一种改进后的turf.idw算法
    基于Geojson的点集的抽稀Js实现
    OL3-Cesium 二三维鼠标事件统一处理
    About TopoJSON
    基于 geojson数据类型面转线Transforms Polygons and MultiPolygons to LineStrings.
    数据库文档编写辅助脚本
    Extensible Messaging and Presence Protocol (XMPP): Core
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6361422.html
Copyright © 2011-2022 走看看