NOI2015 軟體包管理器(樹鏈刨分)

2022-05-06 23:39:11 字數 1962 閱讀 8909

其實也算是個板子吧,思想還是很好的

一開始真的沒什麼思路,然後想了想要是這個軟體已經裝上了就設成1,不然設成0,

查詢的話直接做點到根節點的權值和就好了,要是解除安裝了,就查詢這個點為為根節點的權值和,然後用子樹大小減去上面的權值和就好了

區間覆蓋的話將lazytag改動一下就好了

題面放上醜醜的**

#include#define ls(x) x<<1

#define rs(x) x<<1|1

using

namespace

std;

const

int n=4e5+6

;int

m,n,k,p,l,cnt,tot,res,root;

intlg[n],sum[n],son[n],fa[n],dep[n],top[n],head[n],size[n],id[n];

struct

edge

e[n];

void add_edge(int a,int

b)void push_up(int

p)void build(int p,int l,int

r)

int mid=(l+r)>>1

; build(ls(p),l,mid);

build(rs(p),mid+1

,r);

push_up(p);

}void push_down(int p,int

lenn)

void update(int p,int l,int r,int nl,int nr,int

k) push_down(p,(r-l+1

));

int mid=(l+r)>>1

;

if (nl<=mid) update(ls(p),l,mid,nl,nr,k);

if (nr>mid) update(rs(p),mid+1

,r,nl,nr,k);

push_up(p);

}void query(int p,int l,int r,int xl,int

xr) push_down(p,(r-l+1

));

int mid=(l+r)>>1

;

if (xl<=mid) query(ls(p),l,mid,xl,xr);

if (xr>mid) query(rs(p),mid+1

,r,xl,xr);

}void dfs1(int x,int f,int

deep)

}}void dfs2(int x,int

topf)

}int queson(int

x)int querange(int x,int

y)

if (dep[x]>dep[y]) swap(x,y);

res=0

; query(

1,1,n,id[x],id[y]);

ans+=res;

return

ans;

}void uprange(int x,int y,int

k)

if (dep[x]>dep[y]) swap(x,y);

update(

1,1,n,id[x],id[y],k);

}int

main()

dfs1(root,

0,1);

dfs2(root,root);

build(

1,1,n);

scanf("%d

",&m);

string s;int

x;

for (int i=1;i<=m;i++)

if (s=="

uninstall

") }

return0;

}

noi2015軟體包管理器

你決定設計你自己的軟體包管理器。不可避免的,你要解決軟體包之間的依賴關係。如果a依賴b,那麼安裝a之前需安裝b,解除安裝b之前須解除安裝a。0號軟體包不依賴任何軟體包。依賴關係不存在環 包括自環 你的任務是,求出每次安裝 刪除操作會改變多少個包的狀態。安裝乙個已安裝的軟體包,或者解除安裝乙個未安裝的...

Noi2015 軟體包管理器

time limit 10 sec memory limit 512 mb 你決定設計你自己的軟體包管理器。不可避免地,你要解決軟體包之間的依賴問題。如果軟體包a依賴軟體包b,那麼安裝軟體包a以前,必須先安裝軟體包b。同時,如果想要解除安裝軟體包b,則必須解除安裝軟體包a。現在你已經獲得了所有的軟體...

NOI2015 軟體包管理器

樹鏈剖分維護。1表示安裝的狀態,0表示沒有安裝的狀態。如果install就是把當前點到根的所有點都變成1,然後計算前後的 delta 如果uninstall呢,就是把自己的子樹變成0,答案也是前後的 delta 具體可以參照 不過我的 常數好大啊,跑得好慢。如下 include include in...