zoukankan      html  css  js  c++  java
  • bzoj3251

    3251: 树上三角形

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 637  Solved: 262
    [Submit][Status][Discuss]

    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

    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

    HINT

    对于100%的数据,n,q<=100000,点权范围[1,231-1]

     

    Source

    这道题很脑洞。。。首先点权的范围不超过int,如果我们想构造一个序列,正好任意三个构不成三角形,则数列是这个样子的:f[n+2]=f[n+1]+f[n] 这就是斐波那契数列,n在50左右就爆int了,所以

    当n>50说明肯定是满足的,直接输出Y,否则暴力判断是否存在

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define N 200010
    struct edge
    {
        int to,nxt;
    }e[N];
    int n,q,cnt=1;
    int dep[N],head[N];
    ll key[N];
    int fa[N][30];
    inline bool cp(ll x,ll y)
    {
        return x<y;
    }
    inline void link(int u,int v)
    {
        e[++cnt].nxt=head[u];
        head[u]=cnt;
        e[cnt].to=v;
    }
    inline void change(int a,int b) { key[a]=b;}
    inline void dfs(int u,int last)
    {
        for(int i=head[u];i;i=e[i].nxt) if(e[i].to!=last)
        {
            int v=e[i].to;
            fa[v][0]=u;
            dep[v]=dep[u]+1;
            dfs(v,u);
        }
    }
    inline int lca(int u,int v)
    {
        if(dep[u]<dep[v]) swap(u,v);
        for(int i=22;i>=0;i--)
            if((dep[u]-dep[v])&(1<<i)) u=fa[u][i];
        if(u==v) return u;
        for(int i=22;i>=0;i--) if(fa[u][i]!=fa[v][i])
        {
            u=fa[u][i]; v=fa[v][i];     
        }
        return fa[u][0];
    }
    inline void query(int a,int b)
    {
        int x=lca(a,b);
        if(dep[a]+dep[b]-2*dep[x]+1>50) 
        {
            puts("Y");
            return;
        }
        vector<ll> num; num.clear();
        for(int p=a;p!=x;p=fa[p][0]) num.push_back(key[p]);
        for(int p=b;p!=x;p=fa[p][0]) num.push_back(key[p]);
        num.push_back(key[x]);
        if(num.size()<3) 
        {
            puts("N");
            return;
        }
        sort(num.begin(),num.end(),cp);
        for(int i=0;i<num.size()-2;i++) if(num[i]+num[i+1]>num[i+2])
        {
            puts("Y");
            return;
        } 
        puts("N");
    }
     
    int main()
    {
        memset(fa,-1,sizeof(fa));
        scanf("%d%d",&n,&q);
        for(int i=1;i<=n;i++) scanf("%d",&key[i]);
        for(int i=1;i<n;i++) 
        {
            int u,v; scanf("%d%d",&u,&v);
            link(u,v); link(v,u);
        }
        dfs(1,0);
        for(int i=1;i<=22;i++)
            for(int j=1;j<=n;j++) if(fa[j][i-1]!=-1)
                fa[j][i]=fa[fa[j][i-1]][i-1];
        while(q--)
        {
            int opt,a,b; scanf("%d%d%d",&opt,&a,&b);
            if(opt==0) query(a,b);
            if(opt==1) change(a,b);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    PHPCMS V9后台表单向导用户提交的信息新增“修改”的功能
    phpcms V9最实用的23个调用代码
    phpcms V9推荐位无法调用自定义字段的解决方法
    将博客搬至CSDN
    爬取淘宝商品信息selenium+pyquery+mongodb
    selenium库
    requests库+ajax数据分析+多线程爬取头条图集
    requests微博爬取Ajax数据+mongoDB存储
    redis存储
    pymongo操作MongoDB
  • 原文地址:https://www.cnblogs.com/19992147orz/p/6366987.html
Copyright © 2011-2022 走看看