(題目鏈結)
給出一棵樹,每個節點代表乙個軟體包,維護解除安裝和安裝操作。若要解除安裝節點x,那麼必須解除安裝它的子樹上的所有軟體包;若要安裝節點x必須安裝所有它的祖先。每次詢問安裝或解除安裝某個軟體包一共需要安裝或者解除安裝多少個軟體包。
很裸的樹鏈剖分,0表示未安裝,1表示已安裝。安裝操作很好處理對吧,每次對節點x到根節點這條路徑進行查詢和修改即可。對於解除安裝操作,由於子樹的dfs序是連續的,我們維護dfs序,進入x的子樹時的時間戳l[x],退出時的時間戳r[x],查詢和修改線段樹上l[x]與r[x]之間的值即可。
不知為何uoj上陣列要開大2倍才能過。。
// uoj128#include#include#include#include#include#include#include#define mod 1000000007
#define inf 2147483640
#define ll long long
#define free(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout);
using namespace std;
const int maxn=100010;
struct tree tr[maxn<<1];
struct edge e[maxn<<1];
int head[maxn],pos[maxn],size[maxn],deep[maxn],son[maxn],bl[maxn],bin[31],fa[maxn][31],l[maxn],r[maxn];
int cnt,n,q,p;
char s[maxn];
void link(int u,int v)
void build(int k,int s,int t) ;
if (s==t) return;
int mid=(s+t)>>1;
build(k<<1,s,mid);
build(k<<1|1,mid+1,t);
}void pushdown(int k)
void update(int k,int s,int t,int v)
if (tr[k].tag!=-1) pushdown(k);
int mid=(l+r)>>1;
if (t<=mid) update(k<<1,s,t,v);
else if (s>mid) update(k<<1|1,s,t,v);
else update(k<<1,s,mid,v),update(k<<1|1,mid+1,t,v);
tr[k].s=tr[k<<1].s+tr[k<<1|1].s;
}int query(int k,int s,int t)
void dfs1(int x)
}void dfs2(int x,int top)
int solve(int x,int f)
if (pos[x]>=pos[f]) s+=query(1,pos[f],pos[x]),update(1,pos[f],pos[x],1);
return s;
}int main()
dfs1(0);
dfs2(0,0);
build(1,1,n);
scanf("%d",&q);
while (q--)
else
}return 0;
}
UOJ130 NOI2015 荷馬史詩
作者部落格 追逐影子的人,自己就是影子。荷馬 allison 最近迷上了文學。她喜歡在乙個慵懶的午後,細細地品上一杯卡布奇諾,靜靜地閱讀她愛不釋手的 荷馬史詩 但是由 奧德賽 和 伊利亞特 組成的鴻篇巨制 荷馬史詩 實在是太長了,allison 想通過一種編碼方式使得它變得短一些。一部 荷馬史詩 中...
UOJ 131 NOI2015 品酒大會
題鏈 題解 網上大多數的方法都是用並查集維護。這裡呢,給出另一種自己yy的解法 但實際上本質差不多吧 字尾陣列,rmq,單調棧 1 預處理 1 首先對字串字尾排序,得到 sa i rank i height i 2 然後維護出 l i 表示在字尾陣列中,排名最小 記其排名為 l i 的字尾與排名為 ...
UOJ 131 NOI 2015 品酒大會
求出字尾陣列和height陣列後,從大到小掃相似度進行合併,每次相當於合併兩個緊挨著的區間。合併區間可以用並查集來實現,每個區間的資訊都記錄在這個區間的並查集的根上,合併並查集時用乙個根的資訊更新另乙個根的資訊同時計算兩個答案。時間複雜度 o n log n include include incl...