2 条题解

  • 5
    @ 2023-8-7 13:05:01

    点差分板子题。每次将 aia_iai+1a_{i+1} 路径上的所有点权 +1+1 即可,需要注意 a2a_2an1a_{n-1} 会被重复计算一次,最后到达 ana_n 时无需吃糖果,要把这部分减去。

    #include <bits/stdc++.h>
    #define MAXN 300001
    using namespace std;
    int n,u,v,logn;
    int a[MAXN],de[MAXN],d[MAXN];
    int f[MAXN][30];
    vector<int> e[MAXN];
    void dfs(int u){
        for (int i=0;i<e[u].size();i++){
            int v=e[u][i];
            if (v==f[u][0]){
                continue;
            }
            f[v][0]=u;
            de[v]=de[u]+1;
            dfs(v);
        }
    }
    void dfs1(int u){
        for (int i=0;i<e[u].size();i++){
            int v=e[u][i];
            if (v==f[u][0]){
                continue;
            }
            dfs1(v);
            d[u]+=d[v];
        }
    }
    int lca(int x,int y){
        if (de[x]<de[y]){
            swap(x,y);
        }
        for (int i=0,p=de[x]-de[y];p;i++,p>>=1){
            if (p&1){
                x=f[x][i];
            }
        }
        if (x==y){
            return x;
        }
        for (int j=logn;j>=0;j--){
            if (f[x][j]!=f[y][j]){
                x=f[x][j];
                y=f[y][j];
            }
        }
        return f[x][0];
    }
    int main(){
        cin>>n;
        for (int i=1;i<=n;i++){
            cin>>a[i];
        }
        for (int i=1;i<n;i++){
            cin>>u>>v;
            e[u].push_back(v);
            e[v].push_back(u);
        }
        dfs(1);
        logn=log2(n);
        for (int j=1;j<=logn;j++){
            for (int i=1;i<=n;i++){
                f[i][j]=f[f[i][j-1]][j-1];
            }
        }
        for (int i=1;i<n;i++){
            d[a[i]]++,d[a[i+1]]++;
            int LCA=lca(a[i],a[i+1]);
            d[LCA]--,d[f[LCA][0]]--;
        }
        dfs1(1);
        for (int i=2;i<=n;i++){
            d[a[i]]--;
        }
        for (int i=1;i<=n;i++){
            cout<<d[i]<<endl;
        }
    	return 0;
    }
    
    
    • -20
      @ 2023-2-15 17:29:37

      写题解请注意

      鼓励大家写题解,但注意题解格式。

      题解一定要有思路解析或代码注释,能否让别人理解你的思路

      也是你的能力的检验,不要只放无意义的代码给大家复制,那就失去了做题的初心。

      给代码两端加上这个会舒服一些

      ```cpp

      你的代码

      ```

      这个点在键盘的左上角tab上面那个键,注意切换输入法

      #include<iostream>
      using namespace std;
      int main()
      {
          int n;
          cin>>n;//这是一个注释
          return 0;
      }
      

      请注意严禁抄袭题解,写题解不要只放代码,需加上你的思路或代码注释。

      抄袭题解一经发现直接取消成绩。

      题解被删除的可能

      1. 代码不符合格式规范
      2. 没有思路讲解或者没有注释,
      3. 无意义的题解

      大家携手共同维护一个良好的编程环境,如果一经发现,多次作乱。可能会被管理员拉黑,请注意,一旦拉黑即失去登陆资格。

    • 1

    信息

    ID
    1882
    时间
    1000ms
    内存
    256MiB
    难度
    2
    标签
    递交数
    158
    已通过
    101
    上传者