洛谷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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...