洛谷P3178 [HAOI2015]樹上操作

来源:http://www.cnblogs.com/zwfymqz/archive/2017/12/23/8094286.html
-Advertisement-
Play Games

題目描述 有一棵點數為 N 的樹,以點 1 為根,且樹點有邊權。然後有 M 個操作,分為三種:操作 1 :把某個節點 x 的點權增加 a 。操作 2 :把某個節點 x 為根的子樹中所有點的點權都增加 a 。操作 3 :詢問某個節點 x 到根的路徑中所有點的點權和。 輸入輸出格式 輸入格式: 第一行包 ...


題目描述

有一棵點數為 N 的樹,以點 1 為根,且樹點有邊權。然後有 M 個操作,分為三種:操作 1 :把某個節點 x 的點權增加 a 。操作 2 :把某個節點 x 為根的子樹中所有點的點權都增加 a 。操作 3 :詢問某個節點 x 到根的路徑中所有點的點權和。

輸入輸出格式

輸入格式:

 

第一行包含兩個整數 N, M 。表示點數和操作數。接下來一行 N 個整數,表示樹中節點的初始權值。接下來 N-1 行每行兩個正整數 from, to , 表示該樹中存在一條邊 (from, to) 。再接下來 M 行,每行分別表示一次操作。其中第一個數表示該操作的種類( 1-3 ) ,之後接這個操作的參數( x 或者 x a ) 。

 

輸出格式:

 

對於每個詢問操作,輸出該詢問的答案。答案之間用換行隔開。

 

輸入輸出樣例

輸入樣例#1: 複製
5 5
1 2 3 4 5
1 2
1 4
2 3
2 5
3 3
1 2 1
3 5
2 1 2
3 3
輸出樣例#1: 複製
6
9
13

說明

對於 100% 的數據, N,M<=100000 ,且所有輸入數據的絕對值都不

會超過 10^6 。

 

樹鏈剖分的裸題

每次暴力更改就好

註意這題需要開long long

 

 

#include<iostream>
#include<cstdio>
#include<cstring>
#define ls k<<1
#define rs k<<1|1
#define LL long long 
using namespace std;
const LL MAXN=1e6+10;
inline char nc()
{
    static char buf[MAXN],*p1=buf,*p2=buf;
    return p1==p2&&(p1=(p2=buf)+fread(buf,1,MAXN,stdin),p1==p2)?EOF:++*p1;
}
inline LL read()
{
    char c=getchar();LL x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0',c=getchar();}
    return x*f;
}
LL root=1;
struct node
{
    LL u,v,w,nxt;
}edge[MAXN];
LL head[MAXN];
LL num=1;
inline void AddEdge(LL x,LL y)
{
    edge[num].u=x;
    edge[num].v=y;
    edge[num].nxt=head[x];
    head[x]=num++;
}
struct Tree
{
    LL l,r,f,w,siz;
}T[MAXN];
LL a[MAXN],b[MAXN],tot[MAXN],idx[MAXN],deep[MAXN],son[MAXN],top[MAXN],fa[MAXN],cnt=0;
void update(LL k)
{
    T[k].w=T[ls].w+T[rs].w;
}
void PushDown(LL k)
{
    if(!T[k].f) return ;
    T[ls].w+=T[k].f*T[ls].siz;
    T[rs].w+=T[k].f*T[rs].siz;
    T[ls].f+=T[k].f;
    T[rs].f+=T[k].f;
    T[k].f=0;
}
LL dfs1(LL now,LL f,LL dep)
{
    deep[now]=dep;    
    tot[now]=1;
    fa[now]=f;
    LL maxson=-1;
    for(LL i=head[now];i!=-1;i=edge[i].nxt)
    {
        if(edge[i].v==f) continue;
        tot[now]+=dfs1(edge[i].v,now,dep+1);
        if(tot[edge[i].v]>maxson) maxson=tot[edge[i].v],son[now]=edge[i].v;
    }
    return tot[now];
}
void dfs2(LL now,LL topf)
{
    idx[now]=++cnt;
    a[cnt]=b[now];
    top[now]=topf;
    if(!son[now]) return ;
    dfs2(son[now],topf);
    for(LL i=head[now];i!=-1;i=edge[i].nxt)
        if(!idx[edge[i].v])
            dfs2(edge[i].v,edge[i].v);
}
void Build(LL k,LL ll,LL rr)
{
    T[k].l=ll;T[k].r=rr;T[k].siz=rr-ll+1;
    if(ll==rr)
    {
        T[k].w=a[ll];
        return ;
    }
    LL mid=(ll+rr)>>1;
    Build(ls,ll,mid);
    Build(rs,mid+1,rr);
    update(k);
}
void PointAdd(LL k,LL pos,LL val)
{
    if(T[k].l==T[k].r)
    {
        T[k].w+=val;
        return ;
    }
    PushDown(k);
    LL mid=(T[k].l+T[k].r)>>1;
    if(pos<=mid) PointAdd(ls,pos,val);
    if(pos>mid)  PointAdd(rs,pos,val);
    update(k);
}
void IntervalAdd(LL k,LL ll,LL rr,LL val)
{
    if(ll<=T[k].l&&T[k].r<=rr)
    {
        T[k].w+=T[k].siz*val;
        T[k].f+=val;
        return ;
    }
    PushDown(k);
    LL mid=(T[k].l+T[k].r)>>1;
    if(ll<=mid) IntervalAdd(ls,ll,rr,val);
    if(rr>mid)  IntervalAdd(rs,ll,rr,val);
    update(k);
}
LL IntervalAsk(LL k,LL ll,LL rr)
{
    LL ans=0;
    if(ll<=T[k].l&&T[k].r<=rr)
    {
        ans+=T[k].w;
        return ans;
    }
    PushDown(k);
    LL mid=(T[k].l+T[k].r)>>1;
    if(ll<=mid) ans+=IntervalAsk(ls,ll,rr);
    if(rr>mid)  ans+=IntervalAsk(rs,ll,rr);
    return ans;
}
LL TreeSum(LL x,LL y)
{
    LL ans=0;
    while(top[x]!=top[y])//不在同一條鏈內 
    {
        if(deep[top[x]]<deep[top[y]]) swap(x,y);
        ans+=IntervalAsk(1,idx[top[x]],idx[x]);
        x=fa[top[x]]; 
    }
    if(deep[x]>deep[y]) swap(x,y);
    ans+=IntervalAsk(1,idx[x],idx[y]);
    return ans;
}
int main()
{
    #ifdef WIN32
    freopen("a.in","r",stdin);
    #else
    #endif
    memset(head,-1,sizeof(head));
    LL N=read(),M=read();
    for(LL i=1;i<=N;i++) b[i]=read();
    for(LL i=1;i<=N-1;i++)
    {
        LL x=read(),y=read();
        AddEdge(x,y);AddEdge(y,x);
    }
    dfs1(root,0,1);
    dfs2(root,root);
    Build(1,1,N);
    while(M--)
    {
        LL opt=read(),x,val;
        if(opt==1)
        {
            x=read(),val=read();
            PointAdd(1,idx[x],val);
        }
        else if(opt==2)
        {
            x=read(),val=read();
            IntervalAdd(1,idx[x],idx[x]+tot[x]-1,val);
        }
        else
        {
            x=read();
            printf("%lld\n",TreeSum(root,x));
        }
    }
    return 0;
}

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 這個工具類,用線程的方式實現文件的複製,效果勉強還算可以。功能不夠完善。 根據兩個路徑字元串(文件路徑或文件夾路徑),實現文件的複製,具體用的方法,註釋還算清楚。 不能在構造方法里拋出異常,好難受。 ...
  • 1# 判斷二元一次方程ax+by=c是否有整數解: c%gcd(a,b) == 0 2# ab的最小公倍數 = a*b/最大公約數 3# 最大公約數: 輾轉相除法 4# n進位的轉換用% / +迴圈/遞歸來解決. 5# a&1判斷一個數是奇數還是偶數 6# 高精度加法,乘法原理: 7# 整數a/b向 ...
  • UI界面展示: 3D模型界面: 灰度分佈界面: 下麵是源程式: 下一個任務:進行邊界檢測 思路: 文中圖片 鏈接:鏈接:https://pan.baidu.com/s/1hsImLla 密碼:m2ip ...
  • 最近在學django框架,準備用django寫一個博客園的系統,並且在寫的過程中也遇到一些問題,實踐出真知,對django開發web應用方面也有了進一步的瞭解。很多操作實現都是以我所認知的技術完成的,可能存在不合理的地方(畢竟實現的方法多種多樣),基本完成後會將源碼上傳到git,也歡迎各位大神指正。 ...
  • 這次爬取的網站是糗事百科,網址是:http://www.qiushibaike.com/hot/page/1 分析網址,參數'page/'後面的數字'1'指的是頁數,第二頁就是'/page/2',以此類推。。。 一、分析網頁 網頁圖片 然後明確要爬取的元素:作者名、內容、好笑數、以及評論數量 每一個 ...
  • 題目描述 Farmer John has N barren pastures (2 <= N <= 100,000) connected by N-1 bidirectional roads, such that there is exactly one path between any two p ...
  • 一般Web工程通過Jenkins遠程部署到Tomcat,可以採用Maven的tomcat-maven-plugin插件進行部署。最近接觸到Spring Boot工程的部署,由於Spring Boot應用可以使用內部集成的服務容器(如Tomcat),此時無需按原來的方法進行部署。以工程asset_we ...
  • 監督學習 概念: 在有標記的樣本(labels samples)上建立機器學習 1、數據的預處理 機器學習演算法無法理解原始數據,所以需對原始數據進行預處理,常用預處理如下: 預處理主要使用了preprocessing包,所以需對該包進行導入: import numpy as np from skle ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...