4196 Noi2015 軟體包管理器

2021-08-03 08:32:45 字數 1372 閱讀 3306

用樹剖搞出dfs序,這樣能把一棵子樹變成乙個區間,一條鏈變成log個區間。

用線段樹維護一段連續的dfs序中有幾個點。共兩種操作:

第乙個加點,將log個區間中的總點數統計出來,然後填滿,答案為∑(區間長度-原有點數),複雜度o(n(logn)^2)

第二個刪點,把一段區間中的總點數統計出來作為答案,然後全部清空。複雜度o(nlogn)

因為bzoj的時限放到了10秒,所以是可以過的。

**:

#include#includeusing namespace std;

#define rep(i,j,k) for(i=j;i<=k;++i)

#define per(i,j,k) for(i=j;i>=k;--i)

const int n=100005;

int n,m,ans;

int ne[n<<1],he[n],to[n<<1],tot;

int pre[n],son[n],dad[n],dep[n],sz[n],dfn[n],cnt;

int t[n<<2],lz[n<<2];

void add(int x,int y)

void dfs1(int x)

}void dfs2(int x)

void pd(int l,int r,int num)

}void up(int l,int r,int mid,int num)

int ins(int l,int r,int l,int r,int num)

int mid=l+r>>1,tmp=t[num];

if(l<=mid)ins(l,r,l,mid,num<<1);

if(r>mid)ins(l,r,mid+1,r,num<<1|1);

up(l,r,mid,num);

return t[num]-tmp;

}int del(int l,int r,int l,int r,int num)

int mid=l+r>>1,tmp=t[num];

if(l<=mid)del(l,r,l,mid,num<<1);

if(r>mid)del(l,r,mid+1,r,num<<1|1);

up(l,r,mid,num);

return tmp-t[num];

}int main()

dfs1(1);dfs2(1);

scanf("%d",&m);

memset(lz,-1,sizeof lz);

while(m--)

else ans=del(dfn[x],dfn[x]+sz[x]-1,1,n,1);

printf("%d\n",ans);

} return 0;

}

bzoj4196 NOI2015 軟體包管理器

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

bzoj 4196 Noi2015 軟體包管理器

你決定設計你自己的軟體包管理器。不可避免地,你要解決軟體包之間的依賴問題。如果軟體包a依賴軟體包b,那麼安裝軟體包a以前,必須先安裝軟體包b。同時,如果想要解除安裝軟體包b,則必須解除安裝軟體包a。現在你已經獲得了所有的軟體包之間的依賴關係。而且,由於你之前的工作,除0號軟體包以外,在你的管理器當中...

bzoj4196 Noi2015 軟體包管理器

題目大意 有一棵樹,兩個修改 install x 把根節點到 x 軟體路徑上的值全部變為 1 並輸出修改的節點個數 uninstall x 把 x 以及它的子樹的值變為 0 並輸出修改的節點個數 題解 樹鏈剖分,比較一下修改前後值的變化,即為答案 卡點 1.邊忘記開兩倍 c code include...