1. 程式人生 > >【LOJ】 #2130. 「NOI2015」軟件包管理器

【LOJ】 #2130. 「NOI2015」軟件包管理器

stdin mes con 題解 build clas hang AR pair

題解

連樹剖我都寫跪一次,我現在怎麽那麽老年啊= =
簡直滾粗預定了啊。。

我們線段樹維護樹剖只需要資瓷區間覆蓋和區間求和就好了
安裝的時候看看自己到根有多少包裝了,dep減去這個數量就好
卸載的時候看看子樹裏有多少包安裝了就行

代碼

#include <bits/stdc++.h>
//#define ivorysi
#define enter putchar(‘\n‘)
#define space putchar(‘ ‘)
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define eps 1e-8
#define mo 974711 #define MAXN 100005 #define pii pair<int,int> using namespace std; typedef long long int64; typedef double db; template<class T> void read(T &res) { res = 0;char c = getchar();T f = 1; while(c < ‘0‘ || c > ‘9‘) { if(c == ‘-‘) f = -1; c = getchar(); } while
(c >= ‘0‘ && c <= ‘9‘) { res = res * 10 + c - ‘0‘; c = getchar(); } res *= f; } template<class T> void out(T x) { if(x < 0) {putchar(‘-‘);x = -x;} if(x >= 10) { out(x / 10); } putchar(‘0‘ + x % 10); } struct node { int to,next; }E[MAXN * 2]; struct
Tr_node { int L,R; int sum,cover; }tr[MAXN * 4]; int head[MAXN],sumE,N,Q; int dep[MAXN],fa[MAXN],siz[MAXN],son[MAXN]; int dfn[MAXN],idx,top[MAXN],L[MAXN]; void add_cover(int u,int v) { if(v == 1) { tr[u].sum = tr[u].R - tr[u].L + 1; tr[u].cover = 1; } else { tr[u].sum = 0; tr[u].cover = -1; } } void push_down(int u) { if(tr[u].cover) { add_cover(u << 1,tr[u].cover); add_cover(u << 1 | 1,tr[u].cover); tr[u].cover = 0; } } void update(int u) { tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum; } void add(int u,int v) { E[++sumE].to = v; E[sumE].next = head[u]; head[u] = sumE; } void dfs1(int u) { dep[u] = dep[fa[u]] + 1; siz[u] = 1; for(int i = head[u] ; i ; i = E[i].next) { int v = E[i].to; if(v != fa[u]) { fa[v] = u; dfs1(v); siz[u] += siz[v]; if(siz[v] > siz[son[u]]) son[u] = v; } } } void dfs2(int u) { dfn[u] = ++idx; L[idx] = u; if(!top[u]) top[u] = u; if(son[u]) { top[son[u]] = top[u]; dfs2(son[u]); } for(int i = head[u] ; i ; i = E[i].next) { int v = E[i].to; if(v != fa[u] && v != son[u]) dfs2(v); } } void build(int u,int l,int r) { tr[u].L = l;tr[u].R = r; tr[u].cover = tr[u].sum = 0; if(l == r) return; int mid = (l + r) >> 1; build(u << 1,l,mid); build(u << 1 | 1,mid + 1,r); } int Query(int u,int l,int r) { if(tr[u].L == l && tr[u].R == r) return tr[u].sum; push_down(u); int mid = (tr[u].L + tr[u].R) >> 1; if(r <= mid) Query(u << 1,l,r); else if(l > mid) Query(u << 1 | 1,l,r); else return Query(u << 1,l,mid) + Query(u << 1 | 1,mid + 1,r); } void Cover(int u,int l,int r,int v) { if(tr[u].L == l && tr[u].R == r) { add_cover(u,v); return; } push_down(u); int mid = (tr[u].L + tr[u].R) >> 1; if(r <= mid) Cover(u << 1,l,r,v); else if(l > mid) Cover(u << 1 | 1,l,r,v); else Cover(u << 1,l,mid,v),Cover(u << 1 | 1,mid + 1,r,v); update(u); } void Change(int u,int v) { while(u) { Cover(1,dfn[top[u]],dfn[u],v); u = fa[top[u]]; } } int Query_Tr(int u) { int res = 0; while(u) { res += Query(1,dfn[top[u]],dfn[u]); u = fa[top[u]]; } return res; } void Solve() { read(N); int p; for(int i = 2 ; i <= N ; ++i) { read(p);++p;add(i,p);add(p,i); } dfs1(1);dfs2(1); build(1,1,N); read(Q); char s[20]; for(int i = 1 ; i <= Q ; ++i) { scanf("%s",s + 1);read(p); ++p; if(s[1] == ‘i‘) { out(dep[p] - Query_Tr(p)); Change(p,1); } else { out(Query(1,dfn[p],dfn[p] + siz[p] - 1)); Cover(1,dfn[p],dfn[p] + siz[p] - 1,-1); } enter; } } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); return 0; }

【LOJ】 #2130. 「NOI2015」軟件包管理器