考試的時候直接扎第一題上了這到題連暴力都沒打出來t_t;
心路歷程:
其實考試時候還是有可能做出來的,當然關鍵在能否想到線段樹合併。
當時想到了離散化(很慌沒打出來。。。),樹上差分,lca倍增,當時覺滴倍增很難打,一看n<100000,於是選擇
用向上標記法,然而少了一行**,,,,爆零兩行淚。。。
現在看來倍增真是一點不難啊好打有好用,所以不要有為難情緒,剛就完了。(平日板子要多打記熟啊)
之所以沒想到線段樹合併是因為當時真的沒有透徹理解,
所以新知識點還是要知道它能幹什麼,知道它的用處。
離散化用來乾掉1->10^9,考試的時候真的傻認為要是有10^9種不就完了嗎,,,然後發現忘了還有m次操作這東東,所以z離散化後len最大也就m個卡掉了很多
以前乙個物品的題直接dfs,lca樹上差分就行,現在有10^9個(離散後10^5個),空間時間不可能乙個乙個去維護所以 得用線段樹合併。
每個點有很多資訊所以權值線段樹用來優化空間(當然也能優化時間),對每個點動態開樹插入和刪除(lca,f[lca]),最後dfs,父親合併兒子。
所以需維護區間的maxcnt以及其id,在merge時就需要多傳一下l,r(1,len),如果l==r更新maxx值和id,需要注意的是如果maxx<=0,id乾成0(題目要求)。
sd錯誤:merge時忘了加上root[x]=merge,如果root[x]=0,就會...炸。還有空間沒開夠得開到maxn*50。
優化:插入時如果lca==x||lca==y,那就插入了一次刪了一次所以乾脆不插入。。。
#include#include#include
#include
using
namespace
std;
const
int maxn=100050
;bool
mark[maxn];
intn,m,t,ans[maxn],len;
int kpx[maxn],kpy[maxn],kpz[maxn],turn[maxn];//
離線離散化
int deep[maxn],f[maxn][20];//
倍增lca
int sz,root[maxn],cnt[maxn*50],lc[maxn*50],rc[maxn*50],maxx[maxn*50],num[maxn*50];//
線段樹int head[maxn],cntn=1
;struct
nodeline[maxn*2
];void add(int x,int
y)void dfs(int
x) }
}int ask(int x,int
y) }
return f[x][0];}
void insert(int &root,int l,int r,int
x)
int mid=(l+r)/2
;
if(x<=mid) insert(lc[root],l,mid,x);
else insert(rc[root],mid+1
,r,x);
if(maxx[lc[root]]>=maxx[rc[root]]) maxx[root]=maxx[lc[root]],num[root]=num[lc[root]];
else maxx[root]=maxx[rc[root]],num[root]=num[rc[root]];
}void decrease(int &root,int l,int r,int
x)
int mid=(l+r)/2
;
if(x<=mid) decrease(lc[root],l,mid,x);
else decrease(rc[root],mid+1
,r,x);
if(maxx[lc[root]]>=maxx[rc[root]]) maxx[root]=maxx[lc[root]],num[root]=num[lc[root]];
else maxx[root]=maxx[rc[root]],num[root]=num[rc[root]];
}int merge(int x,int y,int l,int
r)
int mid=(l+r)/2
; lc[x]=merge(lc[x],lc[y],l,mid);
rc[x]=merge(rc[x],rc[y],mid+1
,r);
if(maxx[lc[x]]>=maxx[rc[x]]) maxx[x]=maxx[lc[x]],num[x]=num[lc[x]];
else maxx[x]=maxx[rc[x]],num[x]=num[rc[x]];
returnx;}
void dfst(int
x) }
ans[x]=turn[num[root[x]]];
}int
main()
deep[
1]=1
; mark[
1]=1
; dfs(1);
for(int i=1;i<=m;i++)
sort(turn+1,turn+1+m);
len=unique(turn+1,turn+1+m)-(turn+1
);
for(int i=1;i<=m;i++)
for(int i=1;i<=m;i++)
if(x==kpy[i])
insert(root[ kpx[i] ],
1,len,kpz[i]);
insert(root[ kpy[i] ],
1,len,kpz[i]);
decrease(root[x],
1,len,kpz[i]);
decrease(root[ f[x][
0] ],1
,len,kpz[i]);
}memset(mark,
0,sizeof
(mark));
mark[
1]=1
; dfst(1);
for(int i=1;i<=n;i++)
}
雨天的尾巴
acwing連線 bzoj3307 深繪里一直很討厭雨天。灼熱的天氣穿透了前半個夏天,後來一場大雨和隨之而來的洪水,澆滅了一切。雖然深繪里家鄉的小村落對洪水有著頑固的抵抗力,但也倒了幾座老房子,幾棵老樹被連根拔起,以及田地裡的糧食被弄得一片狼藉。無奈的深繪里和村民們只好等待救濟糧來維生。不過救濟糧的...
雨天的尾巴題目解析
考試的時候直接扎第一題上了這到題連暴力都沒打出來t t 心路歷程 其實考試時候還是有可能做出來的,當然關鍵在能否想到線段樹合併。當時想到了離散化 很慌沒打出來。樹上差分,lca倍增,當時覺滴倍增很難打,一看n 100000,於是選擇 用向上標記法,然而少了一行 爆零兩行淚。現在看來倍增真是一點不難啊...
bzoj3307 雨天的尾巴
time limit 10 sec memory limit 128 mb submit 258 solved 121 submit status discuss n個點,形成乙個樹狀結構。有m次發放,每次選擇兩個點x,y 對於x到y的路徑上 含x,y 每個點發一袋z型別的物品。完成 所有發放後,每...