zoukankan      html  css  js  c++  java
  • Codeforces983E. NN country

    新鲜出炉!

    $n leq 200000$的树,给$m leq 200000$条链,$q leq 200000$个询问,每次问一条询问链最少用m条中的几条给定链覆盖其所有边,可能无解。

    首先确定一种贪心策略:$low_x$表示$x$能通过一条链跳到的最高的点(这里吐槽一下,题解描述时的树是反过来的,树根在地上!反人类啊,然后他后面所有的“高”“矮”描述全是反过来的!!!无良出题人),假设询问俩点$u,v$,lca即为$t$,那么先从$u$一直沿着$low$跳到$t$下面一点点,$v$一直沿着$low$跳到$t$下面一点点,这样的步数分别为$a$和$b$,然后答案为$a+b+2$或者$a+b+1$,取决于最后跳到那俩点是否能在一条链上。$low$的计算dfs一次就行(我TM还跑去看代码了),建出$low$的st表之后上面操作可以倍增出,现在开始$v$和$u$表示他们最后跳到比$t$下面一点点的那俩点。

    现在问:一棵树好多链,每次问一个点对有没有可能在一条链上。

    这不是二维数点嘛hhh,dfs序搞出来,然后如果两个询问点子树内有同个链的端点,那就存在。dfs搜一遍(第一维),搜一个点之后,先查询下他对应的另一询问点的子树(第二维),然后把这个点上的“链端点”加到树状数组,然后搜子树(第一维),然后回来再查一次另一询问点的子树(第二维),看两次查的一不一样。

      1 //#include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 //#include<time.h>
      5 //#include<complex>
      6 //#include<set>
      7 //#include<queue>
      8 #include<vector>
      9 #include<algorithm>
     10 #include<stdlib.h>
     11 using namespace std;
     12 
     13 #define LL long long
     14 int qread()
     15 {
     16     char c; int s=0,f=1; while ((c=getchar())<'0' || c>'9') (c=='-') && (f=-1);
     17     do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s*f;
     18 }
     19 
     20 //Pay attention to '-' , LL and double of qread!!!!
     21 
     22 int n,m,lq;
     23 #define maxn 200011
     24 struct Edge{int to,next;}edge[maxn<<1]; int first[maxn],le=2;
     25 void in(int x,int y) {Edge &e=edge[le]; e.to=y; e.next=first[x]; first[x]=le++;}
     26 
     27 int top[maxn],dep[maxn],fa[maxn],size[maxn],ll[maxn],rr[maxn],Time=0,hea[maxn];
     28 void dfs1(int x)
     29 {
     30     size[x]=1; hea[x]=0; Time++; ll[x]=Time;
     31     for (int i=first[x];i;i=edge[i].next)
     32     {
     33         Edge &e=edge[i];
     34         fa[e.to]=x; dep[e.to]=dep[x]+1; dfs1(e.to); size[x]+=size[e.to];
     35         if (size[hea[x]]<size[e.to]) hea[x]=e.to;
     36     }
     37     rr[x]=Time;
     38 }
     39 void dfs2(int x,int tt)
     40 {
     41     top[x]=tt;
     42     if (hea[x]) dfs2(hea[x],tt);
     43     for (int i=first[x];i;i=edge[i].next) if (edge[i].to!=hea[x]) dfs2(edge[i].to,edge[i].to);
     44 }
     45 int lca(int x,int y)
     46 {
     47     while (top[x]!=top[y])
     48     {
     49         if (dep[top[x]]<dep[top[y]]) x^=y^=x^=y;
     50         x=fa[top[x]];
     51     }
     52     if (dep[x]<dep[y]) return x; return y;
     53 }
     54     
     55 int low[maxn][22];
     56 void dfslow(int x)
     57 {
     58     for (int i=first[x];i;i=edge[i].next)
     59     {
     60         Edge &e=edge[i]; dfslow(e.to);
     61         low[x][0]=dep[low[x][0]]<dep[low[e.to][0]]?low[x][0]:low[e.to][0];
     62     }
     63 }
     64 void makelow()
     65 {
     66     for (int j=1;j<=18;j++)
     67         for (int i=1;i<=n;i++)
     68             low[i][j]=low[low[i][j-1]][j-1];
     69 }
     70 
     71 struct Node{int x,y,t,ans;}a[maxn],q[maxn];
     72 vector<int> va[maxn],vb[maxn];
     73 void ina(int x,int y) {va[x].push_back(y);}
     74 void inb(int x,int y) {vb[x].push_back(y);}
     75 
     76 int XX;
     77 int find(int x,int t)
     78 {
     79     if (dep[low[x][18]]>dep[t]) {XX=-0x3f3f3f3f; return -1;}
     80     if (x==t) {XX=-1; return -2;}
     81     int ans=0;
     82     for (int j=18;~j;j--) if (dep[low[x][j]]>dep[t]) x=low[x][j],ans|=(1<<j);
     83     XX=ans; return x;
     84 }
     85 
     86 struct BIT
     87 {
     88     int n,a[maxn];
     89     void clear(int N) {n=N;}
     90     void add(int x,int v) {for (;x<=n;x+=x&-x) a[x]+=v;}
     91     int query(int x) {int ans=0; for (;x;x-=x&-x) ans+=a[x]; return ans;}
     92 }t;
     93 int pp[maxn];
     94 void dfs(int x)
     95 {
     96     for (int sz=vb[x].size(),i=0;i<sz;i++)
     97     {
     98         int u=vb[x][i];
     99         pp[u]=t.query(rr[q[u].y])-t.query(ll[q[u].y]-1);
    100     }
    101     for (int sz=va[x].size(),i=0;i<sz;i++)
    102     {
    103         int u=va[x][i];
    104         if (x==a[u].x) t.add(ll[a[u].y],1);
    105         else t.add(ll[a[u].x],1);
    106     }
    107     for (int i=first[x];i;i=edge[i].next) dfs(edge[i].to);
    108     for (int sz=vb[x].size(),i=0;i<sz;i++)
    109     {
    110         int u=vb[x][i];
    111         if (t.query(rr[q[u].y])-t.query(ll[q[u].y]-1)!=pp[u]) q[u].ans--;
    112     }
    113 }
    114         
    115 int main()
    116 {
    117     n=qread();
    118     for (int i=2,x;i<=n;i++) {x=qread(); in(x,i);}
    119     dep[1]=1; dfs1(1); dfs2(1,1);
    120     
    121     for (int i=1;i<=n;i++) low[i][0]=i;
    122     m=qread();
    123     for (int i=1;i<=m;i++)
    124     {
    125         a[i].x=qread(); a[i].y=qread();
    126         a[i].t=lca(a[i].x,a[i].y);
    127         low[a[i].x][0]=dep[low[a[i].x][0]]<dep[a[i].t]?low[a[i].x][0]:a[i].t;
    128         low[a[i].y][0]=dep[low[a[i].y][0]]<dep[a[i].t]?low[a[i].y][0]:a[i].t;
    129         ina(a[i].x,i); ina(a[i].y,i);
    130     }
    131     dfslow(1); makelow();
    132     
    133     lq=qread();
    134     for (int i=1;i<=lq;i++)
    135     {
    136         q[i].x=qread(); q[i].y=qread();
    137         q[i].t=lca(q[i].x,q[i].y);
    138         q[i].ans=2;
    139         int x=find(q[i].x,q[i].t); q[i].ans+=XX;
    140         int y=find(q[i].y,q[i].t); q[i].ans+=XX;
    141         if (x>0 && y>0) {q[i].x=x; q[i].y=y; inb(x,i);}
    142     }
    143     
    144     t.clear(n);
    145     dfs(1);
    146     for (int i=1;i<=lq;i++) printf("%d
    ",q[i].ans<0?-1:q[i].ans);
    147     return 0;
    148 }
    View Code
  • 相关阅读:
    如何将本地项目发布到gitee?
    spingboot使用redis连接池报错
    swagger2中UI界面接口点击无法展开问题解决
    idea在Mybatis的xml里面写sql时,表名、字段、报红问题的解决方法
    svn如何创建分支
    Java 反射修改类的常量值、静态变量值、属性值
    Vue简单入门
    Ajax原理简说
    《机器学习Python实现_10_15_集成学习_lightgbm_进一步优化》
    《机器学习Python实现_10_14_集成学习_xgboost_优化介绍》
  • 原文地址:https://www.cnblogs.com/Blue233333/p/9052080.html
Copyright © 2011-2022 走看看