P2146 NOI2015 軟體包管理器

2022-04-30 10:51:10 字數 1704 閱讀 1174

p2146 [noi2015]軟體包管理器

樹鏈剖分

帶區間修改線段樹

install操作:該點到根之間修改成1

uni操作:該點及其子樹修改成0

每次操作時和上次的相減一下即可

#include#include

#include

#include

using

namespace

std;

template

inline t min(t &a,t &b)

template

inline t max(t &a,t &b)

template

inline void read(t &x)

template

inline void

output(t x)

if(x<0) putchar('

-'),x=-x;

int wt[50],l=0

;

while(x) wt[++l]=x%10,x/=10

;

while(l) putchar(wt[l--]+48);}

typedef

int arr[100003

];int n,m,cnt,tot; char opt[15

];arr d,fa,siz,bgs,tp,id,hd,ed;

int nxt[200003],poi[200003],sum[400003],tag[400003

];inline

void add_(int x,int

y)inline

void pushdown(int o,int l,int

r)inline

void build(int o,int l,int

r)

int lc=o<<1,rc=o<<1|1,mid=l+((r-l)>>1

); build(lc,l,mid); build(rc,mid+1

,r);

}inline

int update(int o,int l,int r,int x1,int x2,int

v)pushdown(o,l,r);

int lc=o<<1,rc=o<<1|1,mid=l+((r-l)>>1

);

if(x1<=mid) res+=update(lc,l,mid,x1,x2,v);

if(x2>mid) res+=update(rc,mid+1

,r,x1,x2,v);

sum[o]=sum[lc]+sum[rc];

return

res;

}inline

bool if_del(int o,int l,int r,int

x)inline

void dfs1(int x,int

_fa)

}inline

void dfs2(int x,int

_top)

inline

int ins(int

x)//優化:向上跳直到第乙個值為1的點

return res+update(1,1,n,id[tp[x]],id[x],1);}

intmain()

return0;

}

P2146 NOI2015 軟體包管理器

很好的樹剖板子題 操作一 求點x到0的最短路徑 經過的結點個數 路徑上已安裝的軟體包的總個數,同時將經過的路徑上的所有點標記為已安裝。操作二 將子樹代表的那段存安裝包個數的區間清空 或者是說將其sum值賦值為0 此處為了實現標記已安裝和清空,我們用了乙個標記add add i 1 線段樹上的點i及其...

P2146 NOI2015 軟體包管理器

輸入格式 從檔案manager.in中讀入資料。輸入檔案的第1行包含1個整數n,表示軟體包的總數。軟體包從0開始編號。隨後一行包含n 1個整數,相鄰整數之間用單個空格隔開,分別表示1,2,3,n 2,n 1號軟體包依賴的軟體包的編號。接下來一行包含1個整數q,表示詢問的總數。之後q行,每行1個詢問。...

P2146 NOI2015 軟體包管理器

p2146 noi2015 軟體包管理器 一道樹鏈剖分 還算是比較裸的樹剖w 對於查詢 影響數 的話只需要查詢原本根節點值與現根節點值差異就可以了 include include include include include using namespace std define maxn 1002...