講師:張秉中
上次講太少了QQ
ll dfs(vector<int> tree[],int now,int par){
vector<ll> tmp;
for(auto nxt:tree[now]){
if(nxt == par)continue;
tmp.push_back(dfs(tree,nxt,now));
}
sort(tmp.rbegin(),tmp.rend());
ll re = 1;
for(auto &i:tmp){
re*= p;
re += i;
re %= mod;
}
return re;
}
map<vector<int>,int> mp;
int idx = 0;
void dfs1(int now,int par){
vector<int> tmp;
for(auto nxt:tree[now]){
if(nxt == par)continue;
dfs1(nxt,now);
tmp.push_back(dp[nxt]);
}
sort(tmp.begin(),tmp.end());
if(!mp[tmp]){
dp[now] = mp[tmp] = ++idx;
}
else dp[now] = mp[tmp];
return;
}
1
1
1
2
2
2
3
3
4
0
0
2
2
1
3
1
4
4
5
1
0
2
2
1
3
1
4
4
5
1
3
1
5
1
4
1
2
1
1
10
19
3
1
5
1
4
1
2
1
1
10
19
19-3+(10-3) = 23
23
3
1
5
1
4
1
2
1
1
10
19
23-1+(10-1) = 31
23
31
3
1
5
1
4
1
2
1
1
10
19
23-1+(10-1) = 31
23
31
31
3
1
5
1
4
1
2
1
1
10
19
19-5+(10-5) = 19
23
31
31
19
3
1
5
1
4
1
2
1
1
10
19
19-5+(10-5) = 19
23
31
31
19
21
27
36
27
28
0,5,5,5,5,5
0,5,5,5,5,5
0,4,4,4,4,4
0,2,7,7,7,7
0,5,5,5,5,5
0,4,4,4,4,4
0,2,7,11,11,11
const int mxn = 303;
vector<int> tree[mxn];
int dp[mxn][mxn]
void dfs(int now,int par){
for(auto nxt:tree[now]){
if(nxt == par)continue;
dfs(nxt,now);
for(int i = mxn-1;i>=2;i--){
for(int j = 1;j<i;j++){
dp[now][i] = max(dp[now][i],dp[now][i-j]+dp[nxt][j]);
}
}
}
}
sz紀錄目前的子樹大小
const int mxn = 1010;
vector<int> tree[mxn];
int dp[mxn][mxn];
int sz[mxn];
void dfs(int now,int par){
sz[now] = 1;
for(auto nxt:tree[now]){
if(nxt == par)continue;
dfs(nxt,now);
sz[now] += sz[nxt];
for(int i = sz[now];i>=2;i--){
for(int j = max(i-sz[now]+sz[nxt],0);j<=min(i-1,sz[nxt]);j++){
dp[now][i] = max(dp[now][i],dp[now][i-j]+dp[nxt][j]);
}
}
}
}
sz紀錄目前的子樹大小
const int mxn = 1010;
vector<int> tree[mxn];
int dp[mxn][mxn];
int sz[mxn];
void dfs(int now,int par){
sz[now] = 1;
for(auto nxt:tree[now]){
if(nxt == par)continue;
dfs(nxt,now);
for(int i = sz[now];i>=2;i--){
for(int j = 1;j<=sz[nxt];j++){
dp[now][i+j] = max(dp[now][i+j],dp[now][i]+dp[nxt][j]);
}
}
sz[now] += sz[nxt];
}
}
#include <bits/stdc++.h>
using namespace std;
const int mxn = 2e5+10;
int childs[mxn][2];
int par[mxn];
bool get(int id){
if(!id||!par[id])return 0;
if(childs[par[id]][0] == id)return 0;
else if(childs[par[id]][1] == id)return 1;
else{
cout<<"ERROR "<<id<<endl;
return 0;
}
}
void rotate(int id){
push(par[id]);
push(id);
int lr = get(id);
int p = par[id];
int g = par[par[id]];
childs[g][get(p)] = id;
par[id] = g;
childs[p][lr] = childs[id][lr^1];
par[childs[id][lr^1]] = p;
childs[id][lr^1] = p;
par[p] = id;//注意pull的順序
pull(p);
pull(id);
pull(g);
return;
}
zig
zig-zig
zig-zag
void splay(int id){
if(!id)return;
while(par[id]){
if(par[par[id]])push(par[par[id]]);
push(par[id]);
push(id);
if(!par[par[id]]){
rotate(id);
return;
}
if(get(par[id]) == get(id))rotate(par[id]);
else rotate(id);
rotate(id);
}
}
然後pull跟push要記得做
勢能分析
勢能分析
zig
\(c(x) = 1\)
\(\Delta\Phi(x) = log|c'|+log|p'|-log|p|-log|c|\)
\(=log|p'|-log|c|(|p|=|c'|)\)
\( \le log|c'|-log|c|(|p'|\le|c'|)\)
\(c(x)+\Delta \Phi(x) \le 1+log|c'|-log|c| \le 3\times (log|c'|-log|c|)+1\)
zig-zig
\(c(x) = 2\)
\(\Delta\Phi(x) = log|p'|+log|f'|+log|g'|-log|g|-log|f|-log|p|\)
\(=log|f'|+log|g'|-log|f|-log|p|(|g|=|p'|)\)
\(\le log|p'|+log|g'|-2\times log|p| (|p|\le |f| , |f'|\le |p'|)\)
\(又log|g'|+log|p| \le 2\times log \frac{|g'|+|p|}{2}\le 2\times (log|p'|-1)\)
\(因此log|g'| \le 2\times (log|p'|-1)-log|p|\)
\(c(x)+\Delta \Phi(x) \le 3\times (log|p'|-log|p|)\)
zig-zag
\(c(x) = 2\)
\(\Delta\Phi(x) = log|p'|+log|f'|+log|g'|-log|g|-log|f|-log|p|\)
\(=log|f'|+log|g'|-log|f|-log|p|(|g|=|p'|)\)
\(\le log|p'|+log|g'|-2\times log|p| (|p|\le |f| , |f'|\le |p'|)\)
\(\le 2\times (log|p'|-1)-2\times log|p|(因為log|f'|+log|g'| \le log \frac{|f'|+|g'|}{2} \times 2)\)
\(c(x)+\Delta \Phi(x) \le 2\times (log|p'|-log|p|) \le 3\times (log|p'|-log|p|)\)
勢能分析
void merge(int a,int b){
if(!a||!b)return;
splay(a);
splay(b);
push(a);
push(b);
while(childs[a][1]){
a = childs[a][1];
push(a);
}
while(childs[b][0]){
b = childs[b][0];
push(b);
}
splay(a);
push(a);
splay(b);
childs[a][1] = b;
par[b] = a;
pull(a);
return;
}
int find(int head,int k){
if(!k)return 0;
splay(head);
while(head&&k){
push(head);
int ls = childs[head][0],rs = childs[head][1];
if(sz[ls]+1 == k){
splay(head);
return head;
}
else if(sz[ls]+1<k){
k -= sz[ls]+1;
head = rs;
}
else head = ls;
}
splay(head);
return head;
}
pair<int,int> split(int head,int k){
if(k == 0){
splay(head);
return make_pair(0,head);
}
head = find(head,k);
splay(head);
int tmp = childs[head][1];
childs[head][1] = par[tmp] = 0;
pull(tmp);
pull(head);
return make_pair(head,tmp);
}
實
虛
實
虛
makeroot
void makeroot(int now){
access(now);
splay(now);
rev[now] ^=1;
return;
}
findroot
int findroot(int now){
access(now);
splay(now);
while(childs[now][0])now = childs[now][0];
return now;
}
link
void link(int a,int b){
if(findroot(a) == findroot(b))return;
edges.insert({min(a,b),max(a,b)});
makeroot(a);
makeroot(b);
par[b] = a;
}
cut
void cut(int a,int b){
if(findroot(a) != findroot(b))return;
if(a>b)swap(a,b);
if(edges.find({a,b}) == edges.end())return;
edges.erase({a,b});
makeroot(a);
access(b);
splay(b);
par[childs[b][0]] = 0;
childs[b][0] = 0;
pull(b);
return;
}