BZOJ3251 树上三角形

哇啊啊啊,这个题会爆int!!!要记得开long long 啊!没开long long浪费我好长时间啊!!!

这是一个神奇的题emmmmm.......点修改很简单吧,那么其实主要解决的问题就是树上两点之间所有点权中,能否存在任意三个使得它们可以作为边构成三角形。我们考虑什么时候才能构成三角形?显然是\(a+b>c\)的时候吧。

那么接下来我们考虑一下不存在情况——就是这些点权都无法构成三角形的时候,这时候能够存在的点最多有几个呢qwqwq,如果存在的少了的话,显然我们可以直接暴力是不是!

然后观看数据范围,都在\(2^{31}-1\)以内,所以说就算是极限情况——斐波那契数列(也就是前两项加起来正好等于后一项,而且还是满足这种情况下增长最慢的),点的个数也不会多!

写一个程序发现在斐波那契数列第47项的时候就已经爆掉了int,所以我们可以在点数大于47的时候直接输出“Y”!!!

然后其它的就是暴力了吧。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 100010
using namespace std;
int n,q,t;
int fa[MAXN],head[MAXN],dep[MAXN];
long long sum[MAXN],cur[MAXN];
struct Edge{int nxt,to;}edge[MAXN<<1];
inline void add(int from,int to){edge[++t].nxt=head[from],edge[t].to=to,head[from]=t;}
inline void dfs(int now,int pre)
{
    for(int i=head[now];i;i=edge[i].nxt)
    {
        int v=edge[i].to;
        if(v==pre) continue;
        dep[v]=dep[now]+1,fa[v]=now,dfs(v,now);
    }
}
inline void solve(int x,int y)
{
    int cnt=0;
    while(cnt<=47&&x!=y)
    {
        if(dep[x]>dep[y]) cur[++cnt]=sum[x],x=fa[x];
        else cur[++cnt]=sum[y],y=fa[y];
    }
    cur[++cnt]=sum[x];
    if(cnt>=47) {printf("Y\n"); return;}
    sort(&cur[1],&cur[cnt+1]);
    for(int i=1;i<=cnt-2;i++)
        if(cur[i]+cur[i+1]>cur[i+2])
        {
            printf("Y\n");
            return;
        }
    printf("N\n");
}
int main()
{
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++) scanf("%lld",&sum[i]);
    for(int i=1;i<n;i++)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        add(a,b),add(b,a);
    }
    dfs(1,0);
    for(int i=1;i<=q;i++)
    {
        int op,a,b;
        scanf("%d%d%d",&op,&a,&b);
        if(op==0) solve(a,b);
        else sum[a]=b;
    }
    return 0;
}

转载于:https://www.cnblogs.com/fengxunling/p/10240882.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值