題目大意:
有n個軟體安裝包,除第乙個以外,其他的要在另乙個安裝包的基礎上安裝,且無環,問在安裝和解除安裝某個軟體包時,這個操作實際上會改變多少個軟體包的安裝狀態。
思路:
可構成樹,用樹鏈剖分,線段樹。已安裝的為1,未安裝的為0。對於安裝操作,就是詢問x到0的路徑上0的個數,然後把這個路徑賦為1;對於解除安裝操作,就是詢問x的子樹中1的個數,然後把子樹賦為0。
**:
1 #include2 #include3#define m 800500
4using
namespace
std;56
intn,cnt,dfn,hson[m],pa[m],id[m],to[m],top[m],vis[m],last[m],next[m],head[m],deep[m],size[m],sum[m],sz[m],lazy[m];78
void ins(int x,inty)9
1213
void dfs1(int
x)1423}
2425
void dfs2(int x,int
tp)26
3334
void build(int l,int r,int
cur)
3537
int mid=l+r>>1
;38 build(l,mid,cur<<1),build(mid+1,r,cur<<1|1
);39 sz[cur]=sz[cur<<1]+sz[cur<<1|1
];40}41
42void push_down(int
k)4349}
5051
void change(int l,int r,int l,int r,int cur,int
val)
5254
int mid=l+r>>1
; push_down(cur);
55if (r<=mid) change(l,mid,l,r,cur<<1
,val);
56else
if (l>mid) change(mid+1,r,l,r,cur<<1|1
,val);
57else change(l,mid,l,mid,cur<<1,val),change(mid+1,r,mid+1,r,cur<<1|1
,val);
58 sum[cur]=sum[cur<<1]+sum[cur<<1|1
];59}60
61int ask(int l,int r,int l,int r,int
cur)
6269
70void add(int x,int
y)71
80if (deep[x]>deep[y]) swap(x,y);
81 sum+=ask(1,n,id[x],id[y],1
);82 change(1,n,id[x],id[y],1,1
);83 printf("
%d\n
",t-sum);84}
8586
intmain()
8799
return0;
100 }
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...