NOIP模擬測試10 模板

2022-03-16 15:42:57 字數 3006 閱讀 8424

這是道模板題

30分做法:

暴力統計,複雜度$ o(n^2) $,考場上價效比沒有70分的高

70分演算法:

我們發現有40分演算法跟雨天的尾巴很相似,沒有時間限制,直接權值線段樹動態開點+啟發式合併

複雜度$ o(n(log2n)^2) $,考場上我很沙雕地認為它的複雜度是$ o(n^2) $的所以沒敢打,以後得多學一學複雜度分析包括記憶體分析了。

100分演算法:

跟樹鏈剖分的思想有些類似,首先dfs掃一邊,之後以操作次數為鑑定標準求出重兒子,這個分類標準每個人的**可能不太一樣,拿我的來說這兩個時間相差不大(因為我沒有像某cow大神mikufun把整個子樹全都掃一邊)。

這個是以子樹大小為標準的。

這個是以操作次數為標準的。(都好慢啊~)

繼續繼續~

有了重兒子之後事情就簡單一些了,我們可以在dfs的時候把輕兒子的資訊全部合併到自己身上,之後掃一邊重兒子,

把重兒子的資訊在掃的過程中塞到線段樹里(下標是時間,維護貢獻和體積),並且不去刪除它,

然後處理當前節點這樣就可以保證複雜度了。(很巧妙的運用了樹剖的思想)

空間複雜度無法接受每個點都儲存資訊(最壞大概得三萬mb),所以需要及時清空vector

上面我粘的**是錯誤的,因為我這裡只是當x不是重兒子時才把重兒子的資訊暴力傳過去,

但是我沒有考慮如果fa的祖先某乙個不是重兒子,那麼它的父親就需要它的全部資訊來更新線段樹,而這些資訊卻丟失了。

改完之後過了樣例開開心心地交了上去卻mle了,改成刪乙個添乙個卻又tle!很是尷尬,

最後我想出 頹nc哥頹出 了乙個巧妙的辦法:

用乙個陣列記錄某個節點的vector是誰,這樣就可以避免低效地傳遞資訊了。

再優化一下:直接把輕兒子的資訊傳給重兒子(當然,是在處理完重兒子答案之後)

最後我們考慮如何來跟新答案:線段樹二分

記得考慮k是零的情況,所以要把二分邊界設為l=0,r=m,否則。。。

出題人挺良心的,只有5分是有k==0的節點。

就這樣,一道模板題就被我們切啦!

複雜度$ o(n(log2n)^2) $

1 #include2 #include3 #include4 #include5 #include6 #include7 #include

8 #include9 #include10

#define m(a) memset(a,0,sizeof(a))

11#define aa cout<

using

namespace

std;

13const

int n=1e5+10;14

int q,tot,cnt,n,m,k[n],head[n],to[n*2],ne[n*2

],pre[n],size[n],son[n],ans[n],id[n];

15 vectorv[n],g[n];

16 mapma;

17struct treea[n*4

];18

void add(int x,int

y)19

24void dfs(int x,int

fa)2535}

36void build(int k,int l,int

r)37

45int query_size(int k,int l,int

r)46

53int query_w(int k,int l,int

r)54

61void plus(int k,int val,int time,int

f)62

69int mid=(a[k].l+a[k].r)>>1;70

if(time<=mid) plus(k<<1

,val,time,f);

71else plus(k<<1|1

,val,time,f);

72 a[k].w=a[k<<1].w+a[k<<1|1

].w;

73 a[k].s=a[k<<1].s+a[k<<1|1

].s;74}

75int

get(int

x)76

84return query_w(1,1

,l);85}

86void work(int x,int

fa)87

94int pos=0;95

if(son[x])

96104 id[x]=id[son[x]];

105}

106for(int i=head[x];i;i=ne[i])

107115

v[id[y]].clear();

116g[id[y]].clear();

117}

118for(int i=pos;i)

119129

}130

else

131135

}136 ans[x]=get

(x);

137if(son[fa]!=x)

138144

}145

}146

intmain()

147156

for(int i=1;i<=n;i++)

157161 scanf("

%d",&m);

162 build(1,1

,m);

163for(int i=1,x,y;i<=m;i++)

164170 dfs(1,0

);171 work(1,0

);172 scanf("

%d",&q);

173for(int i=1,x;i<=q;i++)

174178

return0;

179 }

NOIP模擬測試10

越考越爛,感覺藥丸 感覺考試策略和心態出了大問題 這是一道以我的名字命名的題目,我很自豪。看了題沒啥思路,開始看資料點。第乙個資料點只有乙個矩形,看出來了單矩形內的式子 2 x 2 x 1 y 2 y 1 5pts get 繼續讀題,還是沒啥思路,去上廁所 回來後繼續想,只能想出 o n 2 的暴力...

NOIP模擬測試22

自 閉 賽 從這次比賽之後題都好難啊qaq 開考一小時內沒動鍵盤。三道題都不會。gg problem a 數論 過於玄學 列舉質因子,往答案裡去加。用來加入的質因子不會很多,質因子大了對答案是不優的。開兩個vector來回倒騰就完了 這題改完感覺也沒啥,為啥考場上就是想不出來啊qxq 1 inclu...

NOIP模擬測試20

liu runda聚聚的饋贈 problem a 周 防自閉題?這道題讓我整個考試都很愉悅 搜就完事了 1 include 2 3intn 4 int a 20 b 20 c 20 d 20 5 long long ans 67 void dfs int day,long long oi,long ...