zoukankan      html  css  js  c++  java
  • 11.03T2 树链剖分

    5956 -- 【模拟试题】相交

    Description

    给你一棵树,每次询问树上两条链是否有交点。

    Input

    第一行n,表示n个结点
    第二行开始n-1行俩个·数x y,表示x,y有一条边
    接下来q,表示q个询问
    接下来q行四个数a b c d,询问a到b的链是否与c到d的链有交点

    Output

    输出Q行(YES或NO)

    Sample Input

    输入1:

    8

    1 2

    1 3

    2 4

    2 5

    5 6

    5 7

    3 8

    4

    2 5 4 3

    5 3 8 8

    5 4 6 7

    4 8 6 7

    输入2:

    15

    2 1

    3 1

    4 2

    5 3

    6 2

    7 2

    8 5

    9 3

    10 6

    11 5

    12 7

    13 11

    14 1

    15 1

    5

    1 2 3 4

    4 7 1 9

    2 3 7 9

    2 6 7 8

    2 1 6 8

    Sample Output

    输出1:

    YES

    NO

    YES

    NO

    输出2:

    YES

    NO

    YES

    YES

    YES

     

    Hint

    30%的数据1≤n,q≤3000
    另外20%数据是一条链
    100%的数据1≤n,q≤100000
     
     

    题意:给你一棵树,每次询问树上两条链是否有交点。

     30% 将第一条链上所有点打上标记,再遍历第二条链,查看第二条链上是 否有打上标记的点。

    另外 20% 树退化为一条链,每次询问等价于查询数轴上两条线段是否相交。 100% 仔细观察不难发现,两条树链相交的充要条件是其中一条路径的顶点 在另一条路径上,每次询问求出 lca 判断即可。

    管他什么正解,直接上树链剖分
    code:
      1 #include<iostream>
      2 #include<cstdio>
      3 #define N 1000006
      4 #define lc (p<<1)
      5 #define rc (p<<1|1) 
      6 using namespace std;
      7 struct node{
      8     int u,v;
      9 }e[N];
     10 int first[N],nxt[N],cnt;
     11 void add(int u,int v){
     12     e[++cnt].u=u;
     13     e[cnt].v=v;
     14     nxt[cnt]=first[u];
     15     first[u]=cnt;
     16 }
     17 struct T{
     18     int l,r,sum,lazy;
     19 }t[N];
     20 void pushup(int p){
     21     t[p].sum=t[lc].sum+t[rc].sum;
     22 }
     23 void pushnow(int p,int v){
     24     t[p].sum+=(t[p].r-t[p].l+1)*v;
     25     t[p].lazy+=v;
     26 }
     27 void pushdown(int p){
     28     if(t[p].lazy){
     29         pushnow(lc,t[p].lazy);
     30         pushnow(rc,t[p].lazy);
     31         t[p].lazy=0;
     32     }
     33 }
     34 void build(int p,int l,int r){
     35     t[p].l=l,t[p].r=r;
     36     if(l==r){
     37         t[p].sum=0;
     38         t[p].lazy=0;
     39         return;
     40     }
     41     int mid=l+r>>1;
     42     build(lc,l,mid);
     43     build(rc,mid+1,r);
     44     pushup(p);
     45 }
     46 void update(int p,int ql,int qr,int v){
     47     if(ql<=t[p].l&&t[p].r<=qr){
     48         pushnow(p,v);
     49         return;
     50     }
     51     pushdown(p);
     52     int mid=t[p].l+t[p].r>>1;
     53     if(ql<=mid)update(lc,ql,qr,v);
     54     if(qr>mid)update(rc,ql,qr,v);
     55     pushup(p);
     56 }
     57 int query(int p,int ql,int qr){
     58     if(ql<=t[p].l&&t[p].r<=qr){
     59         return t[p].sum;
     60     }
     61     int ans=0;
     62     pushdown(p);
     63     int mid=t[p].l+t[p].r>>1;
     64     if(ql<=mid)ans+=query(lc,ql,qr);
     65     if(qr>mid)ans+=query(rc,ql,qr);
     66     pushup(p);
     67     return ans;
     68 }
     69 int siz[N],hson[N],fa[N],dep[N];
     70 void dfs1(int x){
     71     siz[x]=1;
     72     hson[x]=0;
     73     for(int i=first[x];i;i=nxt[i]){
     74         int v=e[i].v;
     75         if(v==fa[x])continue;
     76         fa[v]=x;
     77         dep[v]=dep[x]+1;
     78         dfs1(v);
     79         siz[x]+=siz[v];
     80         if(!hson[x]||siz[hson[x]]<siz[v])hson[x]=v;
     81     }
     82 }
     83 int top[N],num[N],pre[N],tot;
     84 void dfs2(int x,int tp){
     85     top[x]=tp;
     86     num[x]=++tot;
     87     pre[tot]=x;
     88     if(hson[x])dfs2(hson[x],tp);
     89     for(int i=first[x];i;i=nxt[i]){
     90         int v=e[i].v;
     91         if(v==fa[x]||v==hson[x])continue;
     92         dfs2(v,v);
     93     }
     94 }
     95 void modify(int x,int y,int v){
     96     while(top[x]!=top[y]){
     97         if(dep[top[x]]<dep[top[y]])swap(x,y);
     98         update(1,num[top[x]],num[x],v);
     99         x=fa[top[x]];
    100     }
    101     if(dep[x]<dep[y])swap(x,y);
    102     update(1,num[y],num[x],v);
    103 }
    104 int ask_sum(int x,int y){
    105     int ans=0;
    106     while(top[x]!=top[y]){
    107         if(dep[top[x]]<dep[top[y]])swap(x,y);
    108         ans+=query(1,num[top[x]],num[x]);
    109         x=fa[top[x]];
    110     }
    111     if(dep[x]<dep[y])swap(x,y);
    112     ans+=query(1,num[y],num[x]);
    113     return ans;
    114 }    
    115 int read(){
    116     int x=0,f=1;
    117     char c=getchar();
    118     while(!isdigit(c)){
    119         if(c=='-')f=-1;
    120         c=getchar();
    121     }
    122     while(isdigit(c)){
    123         x=(x<<1)+(x<<3)+c-'0';
    124         c=getchar();
    125     }
    126     return x*f;
    127 }
    128 int main(){
    129     int n;
    130     n=read();
    131     for(int i=1;i<n;i++){
    132         int u,v;
    133         u=read(),v=read();
    134         add(u,v);
    135         add(v,u);
    136     }
    137     dfs1(1);
    138     dfs2(1,1);
    139     build(1,1,n);
    140     int m;
    141     m=read();
    142     for(int i=1;i<=m;i++){
    143         int a,b,c,d;
    144         a=read(),b=read(),c=read(),d=read();
    145         modify(a,b,1);
    146         if(ask_sum(c,d))cout<<"YES"<<'
    ';
    147         else cout<<"NO"<<'
    ';
    148         modify(a,b,-1);
    149     }
    150 }
    151 //调试语句注意  

    over

  • 相关阅读:
    人脸识别常用数据集大全(12/20更新)
    103 保序回归 isotonic regression
    SVM的概率输出(Platt scaling)
    scikit_learn 中文说明入门
    外点惩处函数法·约束优化问题
    unigui 设置单元格颜色
    一些仪器的解码程序(delphi)
    phpstudy 配置 memcached / memcache
    OmniThreadLibrary学习笔记
    注意微信支付的配置
  • 原文地址:https://www.cnblogs.com/saionjisekai/p/9902347.html
Copyright © 2011-2022 走看看