动态数组建树

Tree

Problem Description
wls 有三棵树,树上每个节点都有一个值 ai,现在有 2 种操作:

  1. 将一条链上的所有节点的值开根号向下取整;
  2. 求一条链上值的和;
    链的定义是两点之间的最短路。

Input
第一行两个数 n, q 分别代表树上点的数量和操作数量。
第二行 n 个整数,第 i 个数代表第 i 个点的值 ai。
接下来 n − 1 行, 每行两个整数 u, v 代表 u,v 之间有一条边。数据保证点两两联通。
接下来 q 行,每行有个整数 op, u, v,op = 0 表示将 u, v 这条链上所有的点的值开根号向下取整,op = 1表示询问 u,v 这条链上的值的和。
1 ≤ n, q ≤ 100, 000
0 ≤ ai ≤ 1, 000, 000, 000

Output
对于每一组 op = 2 的询问,输出一行一个值表示答案。

Sample Input

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

Sample Output

2
4

Source
2019中国大学生程序设计竞赛-女生专场(重现赛)-感谢南京晓庄学院
HINT
用动态数组存 思路简单 一个树的结构。然后进行操作。如果原理搞不懂先去学学数据结构比较好理解。
Code:

#include<bits/stdc++.h>
using namespace std;
const int maxx=100010;
struct node
{
    int nt,w;
};
vector<node>v[maxx];
bool book[maxx];
int pre[maxx],dth[maxx],val[maxx],qwq[maxx];
int dfs(int x)
{
    book[x]=1;
    for(int i=0;i<v[x].size();i++)
    {
        if(book[v[x][i].nt])continue;
        pre[v[x][i].nt]=x;
        dth[v[x][i].nt]=dth[x]+1;
        dfs(v[x][i].nt);
    }
}
int f(int x,int y,int op)
{
    int cnt=0,flag=0;
    while(x!=y)
    {
        if(dth[x]>=dth[y])
        {
            qwq[cnt++]=x;
            x=pre[x];
            flag=0;
        }else
        {
            qwq[cnt++]=y;
            y=pre[y];
            flag=1;
        }
    }
    if(flag==0)qwq[cnt++]=x;
    else qwq[cnt++]=x;
    if(op==0)
    {
        for(int i=0;i<cnt;i++)
            val[qwq[i]]=sqrt(val[qwq[i]]);
    }else
    {
        long long sum=0;
        for(int i=0;i<cnt;i++)
            sum+=val[qwq[i]];
        printf("%lld\n",sum);
    }
    return 0;
}
int main()
{
    int n,q;
    scanf("%d %d",&n,&q);
    int x,y;
    node a;
    for(int i=1;i<=n;i++)scanf("%d",&val[i]);
    for(int i=0;i<n-1;i++)
    {
        scanf("%d %d",&x,&y);
        a.nt=y;
        v[x].push_back(a);
        a.nt=x;
        v[y].push_back(a);
    }
    dfs(1);
    for(int i=0;i<q;i++)
    {
        int x,y,op;
        scanf("%d %d %d",&op,&x,&y);
        f(x,y,op);
    }
    return 0;
}

Saber
Time Limit: 2 Seconds Memory Limit: 65536 KB
Saber is a Class in the Holy Grail War. This Class is regarded as one of the most powerful Class.
动态数组建树
Saber is a tree-lover. She loves all kinds of trees. One day, she suddenly comes up with a curious problem. She wants to know that in the path between x and y, whether it exists that when we choose three different edges i,j,k, the length of these three edges can build a triangle. Now she wants you to solve this problem.

Input

There are multiple test cases. The first line of input contains an integer T(T ≤ 5), indicating the number of test cases. For each test case:

The first line contains one integer N(1 ≤ N ≤ 100000), indicating the number of tree’s vertices. In the following N-1 lines, there are three integers x, y, w (1 ≤ w ≤ 1000000000), indicating an edge weighted w between x and y.

In the following line also contains one integer Q(1 ≤ Q ≤ 100000), indicating the number of queries. In the following Q lines, there are two integers x, y, indicating a query between x and y.

Output

For each test case output ‘Case #i:’ in the first line, i equals to the case number. Then for every query output ‘Yes’ or ‘No’ in one line.

Sample Input

2
5
1 2 5
1 3 20
2 4 30
4 5 15
2
3 4
3 5
5
1 4 32
2 3 100
3 5 45
4 5 60
2
1 4
1 3

Sample Output

Case #1:
No
Yes
Case #2:
No
Yes

Code:

#include<bits/stdc++.h>
using namespace std;
const int maxn=100010;
struct node
{
    int nt,w;
};
vector<node>v[maxn];
bool book[maxn];
int dth[maxn],val[maxn],pre[maxn];
int qwq[55];
void dfs(int x)
{
    book[x]=1;
    for(int i=0; i<v[x].size(); i++)
    {
        if(book[v[x][i].nt])
            continue;
        pre[v[x][i].nt]=x;
        dth[v[x][i].nt]=dth[x]+1;
        val[v[x][i].nt]=v[x][i].w;
        dfs(v[x][i].nt);
    }
}
int f(int x,int y)
{
    int cnt=0;
    while(x!=y)
    {
        if(cnt>=50)
            return 1;
        else
        {
            if(dth[x]>=dth[y])
            {
                qwq[cnt++]=val[x];
                x=pre[x];
            }
            else
            {
                qwq[cnt++]=val[y];
                y=pre[y];
            }
        }
    }
    sort(qwq,qwq+cnt);
    for(int i=0; i<cnt-2; i++)
    {
        if(qwq[i]+qwq[i+1]>qwq[i+2])
            return 1;
    }
    return 0;
}
int main()
{
    int t,n;
    scanf("%d",&t);
    int ca=0;
    while(t--)
    {
        memset(book,0,sizeof(book));
        printf("Case #%d:\n",++ca);
        scanf("%d",&n);
        for(int i=0; i<=n; i++)
            v[i].clear();
        int x,y,w;
        node a;
        for(int i=1; i<n; i++)
        {
            scanf("%d%d%d",&x,&y,&w);
            a.nt=y;
            a.w=w;
            v[x].push_back(a);
            a.nt=x;
            a.w=w;
            v[y].push_back(a);
        }
        dfs(1);
        int q;
        scanf("%d",&q);
        while(q--)
        {
            int qx,qy;
            scanf("%d%d",&qx,&qy);
            if(qx>qy)
                swap(qx,qy);
            int f1=0;
            f1=f(qx,qy);
            printf(f1?"Yes\n":"No\n");
        }
    }
    return 0;
}

上一篇:AC自动机模板题


下一篇:splay区间操作(bzoj1500)