zoukankan      html  css  js  c++  java
  • BZOJ3251:树上三角形(乱搞)

    Description

    给定一大小为n的有点权树,每次询问一对点(u,v),问是否能在u到v的简单路径上取三个点权,以这三个权值为边长构成一个三角形。同时还支持单点修改。

    Input

    第一行两个整数n、q表示树的点数和操作数
    第二行n个整数表示n个点的点权
    以下n-1行,每行2个整数a、b,表示a是b的父亲(以1为根的情况下)
    以下q行,每行3个整数t、a、b
    若t=0,则询问(a,b)
    若t=1,则将点a的点权修改为b
    n,q<=100000,点权范围[1,2^31-1]

    Output

    对每个询问输出一行表示答案,“Y”表示有解,“N”表示无解。

    Sample Input

    5 5
    1 2 3 4 5
    1 2
    2 3
    3 4
    1 5
    0 1 3
    0 4 5
    1 1 4
    0 2 5
    0 2 3

    Sample Output

    N
    Y
    Y
    N

    Solution

    考虑对于一个询问的一个树链,如果我们自己构造,让他不含三角形我们会怎么构造:

    肯定是像$1,2,3,5,8,13$一样,类似斐波那契数列。

    而斐波那契又是增长非常快的,所以当询问的树链长度超过一个值(我设的$50$个点)就肯定$Y$,否则就暴力。

    Code

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<vector>
     5 #include<algorithm>
     6 #define N (100009)
     7 using namespace std;
     8 
     9 struct Edge{int to,next;}edge[N<<2];
    10 int n,q,a[N],f[N][18],Depth[N];
    11 int head[N],num_edge;
    12 vector<int>v;
    13 
    14 inline int read()
    15 {
    16     int x=0,w=1; char c=getchar();
    17     while (c<'0' || c>'9') {if (c=='-') w=-1; c=getchar();}
    18     while (c>='0' && c<='9') x=x*10+c-'0', c=getchar();
    19     return x*w;
    20 }
    21 
    22 void add(int u,int v)
    23 {
    24     edge[++num_edge].to=v;
    25     edge[num_edge].next=head[u];
    26     head[u]=num_edge;
    27 }
    28 
    29 void DFS(int x,int fa)
    30 {
    31     f[x][0]=fa; Depth[x]=Depth[fa]+1;
    32     for (int i=1; i<=17; ++i)
    33         f[x][i]=f[f[x][i-1]][i-1];
    34     for (int i=head[x]; i; i=edge[i].next)
    35         if (edge[i].to!=fa) DFS(edge[i].to,x);
    36 }
    37 
    38 int LCA(int x,int y)
    39 {
    40     if (Depth[x]<Depth[y]) swap(x,y);
    41     for (int i=17; i>=0; --i)
    42         if (Depth[f[x][i]]>=Depth[y]) x=f[x][i];
    43     if (x==y) return x;
    44     for (int i=17; i>=0; --i)
    45         if (f[x][i]!=f[y][i]) x=f[x][i], y=f[y][i];
    46     return f[x][0];
    47 }
    48 
    49 void Solve(int x,int y,int lca)
    50 {
    51     v.clear();
    52     while (x!=lca) v.push_back(a[x]), x=f[x][0];
    53     while (y!=lca) v.push_back(a[y]), y=f[y][0];
    54     v.push_back(a[lca]);
    55     sort(v.begin(),v.end());
    56     for (int i=1,s=v.size(); i<s-1; ++i)
    57         if (1ll*v[i-1]+v[i]>v[i+1]) {puts("Y"); return;}
    58     puts("N");
    59 }
    60 
    61 int main()
    62 {
    63     n=read(); q=read();
    64     for (int i=1; i<=n; ++i) a[i]=read();
    65     for (int i=1;  i<=n-1; ++i)
    66     {
    67         int u=read(),v=read();
    68         add(u,v); add(v,u);
    69     }
    70     DFS(1,0);
    71     while (q--)
    72     {
    73         int opt=read(),x=read(),y=read();
    74         if (opt==0)
    75         {
    76             int lca=LCA(x,y);
    77             if (Depth[x]-Depth[lca]+Depth[y]-Depth[lca]+1>50) puts("Y");
    78             else Solve(x,y,lca);
    79         }
    80         else a[x]=y;
    81     }
    82 }
  • 相关阅读:
    2021.1.28 个人rating赛补题报告
    2021.1.23 个人rating赛补题报告
    2021.1.23 个人rating赛补题报告
    2020.12.14 个人训练赛补题报告
    2020.11.28 2020团体程序设计天梯赛补题报告
    2020.12.3 Codeforces Beta Round #73(Div2)补题报告
    Xhorse VVDI Prog V5.0.6 is Ready for BCM2 Adapter
    Program 2021 Ford Bronco All Keys Lost using VVDI Key Tool Plus
    Xhorse VVDI Prog V5.0.4 Software Update in July 2021
    How to use Xhorse VVDI2 to Exchange BMW FEM/BDC Module?
  • 原文地址:https://www.cnblogs.com/refun/p/10395497.html
Copyright © 2011-2022 走看看