Hrbust 2064 萌萌哒十五酱的宠物~(树链剖分+线段树)

来源:互联网 发布:lcd1602不显示数据 编辑:程序博客网 时间:2024/04/30 05:37

萌萌哒十五酱的宠物~

Time Limit: 2000 MS Memory Limit: 32768 K

Total Submit: 48(16 users) Total Accepted: 22(14 users) Rating: Special Judge: No

Description

十五酱养了一只很可爱的宠物。。。。。。 一只虫子。。。。TAT 这只虫子特别喜欢爬树。。。。。它在这棵树上生活了很久,对它的构造了如指掌。所以它在树上从来都是走最短路,不会绕路。它还还特别喜欢三角形,所以当它在树上爬来爬去的时候总会在想,如果把刚才爬过的那几根树枝/树干锯下来,能不能从中选三根出来拼成一个三角形呢? 

Input

多组数据 每组数据第一行包含一个整数 N(N<=100000),表示树上节点的个数(从 1 到 N 标号)。 接下来的 N-1 行包含三个整数 a, b, len(1<=a<=N,1<=b<=N,1<=len<=10^9),表示有一根长度为 len 的树枝/树干在节点 a 和节点 b 之间。接下来一行包含一个整数 M(M<=100000),表示询问数。接下来M行每行两个整数 S, T,表示毛毛虫从 S 爬行到了 T,询问这段路程中的树枝/树干是否能拼成三角形。 

Output
多组数据
对于每个询问输出一行,包含”Yes”或“No”,表示是否可以拼成三角形。
Sample Input
5
1 2 5
1 3 20
2 4 30
4 5 15
2
3 4
3 5

Sample Output
No
Yes
题解:要想数列不能组成三角形,则应满足斐波那契数列,ai<1e9.如果边数>50,则一定能组成三角形。不行就暴力判断。
代码:

#include<iostream>#include<stdio.h>#include<stdlib.h>#include<string.h>#include<vector>#include<queue>#include<stack>#include<set>#include<algorithm>#include<map>#include<time.h>#include<math.h>//#define pb push_back//#define mp make_pair#define INF 0x3f3f3f3fusing namespace std;typedef long long int ll;typedef pair<int,int>pp;const int N=1e3+100;const int mod=1e9+7;int read(){    int x=0;    char ch = getchar();    while('0'>ch||ch>'9')ch=getchar();    while('0'<=ch&&ch<='9')    {        x=(x<<3)+(x<<1)+ch-'0';        ch=getchar();    }    return x;}/***********************************************************/struct node{    int to;    int w;    int next;}e[250000];int val[150000];int head[150000];int n,cont;void add(int from,int to,int w){    e[cont].to=to;    e[cont].w=w;    e[cont].next=head[from];    head[from]=cont++;}#define lson l,m,rt*2#define rson m+1,r,rt*2+1int tree[155000*10];void pushup(int rt){    tree[rt]=tree[rt<<1]+tree[rt<<1|1];}void update(int L,int R,int c,int l,int r,int rt){    if(L<=l&&r<=R)    {        tree[rt]=c;        return ;    }    int m=(l+r)/2;    if(L<=m)    {        update(L,R,c,lson);    }    if(m<R)    {        update(L,R,c,rson);    }    pushup(rt);}int Query(int L,int R,int l,int r,int rt){    if(L<=l&&r<=R)    {        return tree[rt];    }    else    {        int m=(l+r)>>1;        int ans=0;        if(L<=m)        {            ans+=Query(L,R,lson);        }        if(m<R)        {            ans+=Query(L,R,rson);        }        pushup(rt);        return ans;    }}void build( int l ,int r , int rt ){    if( l == r )    {        tree[rt]=0;        return ;    }    else    {        int m = (l+r)>>1 ;        build(lson) ;        build(rson) ;        pushup(rt) ;        return ;    }}int cnt;int depth[150000];int son[150000];int fa[150000];int size[150000];int dfn[150000];int Top[150000];void Dfs(int u,int from,int d){    size[u]=1;fa[u]=from;son[u]=-1;depth[u]=d;    for(int i=head[u];i!=-1;i=e[i].next)    {        int v=e[i].to;        if(v==from)continue;        Dfs(v,u,d+1);        size[u]+=size[v];        if(son[u]==-1||size[v]>size[son[u]])        {            son[u]=v;        }    }}void Dfs2(int u,int top){    Top[u]=top;dfn[u]=++cnt;    if(son[u]!=-1)Dfs2(son[u],top);    for(int i=head[u];i!=-1;i=e[i].next)    {        int v=e[i].to;        if(v==fa[u]||v==son[u])continue;        Dfs2(v,v);    }}void Slove2(int x,int y){    int cnt=0;    int path[500];    while(x!=y)    {        if(depth[x]<depth[y])swap(x,y);        path[cnt++]=val[x];        x=fa[x];    }    int flag=0;    sort(path,path+cnt);    for(int i=2;i<cnt;i++)    {        if(path[i-2]+path[i-1]>path[i])flag=1;    }    if(flag==1)printf("Yes\n");    else printf("No\n");}void Slove(int x,int y){    int prex=x,prey=y;    int sum=0;    int fx=Top[x],fy=Top[y];    while(fx!=fy)    {        if(depth[fx]<depth[fy])        {            swap(fx,fy);swap(x,y);        }        sum+=Query(dfn[fx],dfn[x],1,n,1);        x=fa[fx];fx=Top[x];    }    if(depth[x]<depth[y])swap(x,y);    if(x!=y)    sum+=Query(dfn[son[y]],dfn[x],1,n,1);    if(sum>=100)printf("Yes\n");    else Slove2(prex,prey);}int xx[150000],yy[150000],ww[150000];int main(){    while(~scanf("%d",&n))    {        cnt=0;        cont=0;        memset(head,-1,sizeof(head));        for(int i=1;i<=n-1;i++)        {            int x,y,w;scanf("%d%d%d",&x,&y,&w);            xx[i]=x;yy[i]=y;ww[i]=w;            add(x,y,w);            add(y,x,w);        }        Dfs(1,-1,1);        Dfs2(1,1);        build(1,n,1);            for(int i=1;i<=n-1;i++)        {            if(depth[xx[i]]<depth[yy[i]])swap(xx[i],yy[i]);            val[xx[i]]=ww[i];        }        for(int i=2;i<=n;i++)update(dfn[i],dfn[i],1,1,n,1);        int q;        scanf("%d",&q);        while(q--)        {            int x,y;            scanf("%d%d",&x,&y);            Slove(x,y);        }    }    return 0;}