cjtsai
失蹤的c++殭屍
cjtsai
我上次講小社是11/17欸 燒雞
可以吃嗎
根節點
葉節點
父節點
子節點
正向情說為甚麼
要用黑底白圖
所以我把它調成白底了
最長的那條
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
const int maxn = 2e5+5;
vector<int> adj[maxn];
void dfs(int i, vector<int> & dep, vector<bool> & visited) {
visited[i] = 1;
for (auto &v : adj[i]) {
if (!visited[v]) {
dep[v] = dep[i]+1;
dfs(v, dep, visited);
}
}
}
signed main(){
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int n;
cin >> n;
for (int i = 0; i < n-1; ++i) {
int a, b;
cin >> a >> b;
adj[a].push_back(b);
adj[b].push_back(a);
}
vector<int> dep(n+1, 0);
vector<bool> visited(n+1, 0);
dfs(1, dep, visited);
int maxDeepNode = 1;
for (int i = 1; i <= n; ++i) {
if (dep[i] > dep[maxDeepNode]) maxDeepNode = i;
}
fill(dep.begin(), dep.end(), 0);
fill(visited.begin(), visited.end(), 0);
dfs(maxDeepNode, dep, visited);
int diameter = 0;
for (auto &i : dep) diameter = max(i, diameter);
cout << diameter << endl;
return 0;
}
低批好難
#include<bits/stdc++.h>
using namespace std;
vector<vector<int>> sub(200007);
vector<int> ans(200007, 0);
int solve(int ind){
for(int x:sub[ind]){
solve(x);
ans[ind]+=ans[x]+1;
}return ans[ind];
}
int main(){
ios_base::sync_with_stdio(false);cin.tie(0);
int n;cin>>n;
for(int i=2; i<=n; i++){
int a;cin>>a;
sub[a].push_back(i);
}
solve(1);
for(int i=1; i<=n; i++) cout<<ans[i]<<' ';
}
#include <bits/stdc++.h>
using namespace std;
#define pb push_back
vi adj[200005];
int dp[200005][2];
void dfs(int v, int p) {
for (int to : adj[v]) {
if (to != p) {
dfs(to, v);
dp[v][0] += max(dp[to][0], dp[to][1]);
}
}
for (int to : adj[v]) {
if (to != p) {
dp[v][1] = max(dp[v][1], dp[to][0] + 1 + dp[v][0] -
max(dp[to][0], dp[to][1]));
}
}
}
int main() {
ios_base::sync_with_stdio(0);cin.tie(0);;
int n;
cin >> n;
for (int i = 0; i < n - 1; i++) {
int u, v;
cin >> u >> v;
u--, v--;
adj[u].pb(v), adj[v].pb(u);
}
dfs(0, -1);
cout << max(dp[0][0], dp[0][1]) << '\n';
}
#include<iostream>
#include<vector>
#include<algorithm>
#define ll long long
using namespace std;
vector<ll> sub,dp;
vector<vector<int>> graph;
int n;
void dfs1(int node,int parent){
for(auto x:graph[node]){
if(x==parent) continue;
dfs1(x,node);
sub[node]+=sub[x];
}
sub[node]++;
}
void dfs2(int node,int parent){
for(auto x:graph[node]){
if(x==parent) continue;
dp[x]=dp[node]+1;
dfs2(x,node);
}
}
void dfs3(int node,int parent){
for(auto x:graph[node]){
if(x==parent) continue;
dp[x]=dp[node]-sub[x]+n-sub[x];
dfs3(x,node);
}
}
int main(){
cin>>n;
int a,b;
sub.resize(n+1);
dp.resize(n+1);
graph.resize(n+1);
for(int i=1;i<n;i++){
cin>>a>>b;
graph[a].push_back(b);
graph[b].push_back(a);
}
dfs1(1,0);
dfs2(1,0);
for(int i=2;i<=n;i++) dp[1]+=dp[i];
for(int i=2;i<=n;i++) dp[i]=0;
dfs3(1,0);
for(int i=1;i<=n;i++) cout<<dp[i]<<' ';
}
Acme Engineering is a full service software agency.
int siz[maxn];
void dfs(int n, int par) {
siz[n] = 1;
for (int v:adj[n]) {
if (v != par) {
dfs(v, n);
siz[n] += siz[v];
}
}
}
int tot; //總節點數
int get_centroid(int n, int par) {
for (int v:adj[n]) {
if (v != par && siz[v] * 2 > tot) {
return get_centroid(v, n);
}
}
return n;
}
int main() {
dfs(1, 0);
int centroid = get_centroid(1, 0);
}
熱壓吐司
1
2
3
4
5
6
7
8
9
10
11
12
13
15
14
16
17
18
21
19
20
22
1
2
3
4
5
6
7
8
9
10
11
12
13
15
14
16
17
18
21
19
20
22
1
2
3
4
5
6
7
8
9
10
11
12
13
15
14
16
17
18
21
19
20
22
1
2
3
4
5
6
7
8
9
10
11
1
2
3
4
5
6
7
8
9
10
11
12
13
15
14
16
17
18
21
19
20
22
1
2
3
4
5
6
7
8
9
10
11
1
2
3
4
5
6
7
8
9
10
11
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int,int>
#define pb push_back
#define all(x) x.begin(),x.end()
#define ff first
#define ss second
vector<int> pa(300000+1), in(300000+1, -1), out(300000+1);
vector<vector<int>> ch(300000+1);
vector<int> st(1000010, 0);
vector<int> dfn;
int n;
void dfs(int root){
dfn.pb(root);
for(int x:ch[root]){
dfs(x);
}
dfn.pb(root);
}
int query(int l, int r) {
int sum=0;
for(l+=2*n,r+=2*n;l<r;l>>=1,r>>=1){
if(l&1)sum+=st[l++];
if(r&1)sum+=st[--r];
}
return sum;
}
int build(){
for(int i=2*n; i<4*n; i++)st2[i]=dfn[i-2*n];
for(int i=2*n-1;i>=0; i--)st2[i]=min(st2[i*2+1], st2[i*2]);
}
signed main(){
ios_base::sync_with_stdio(false);cin.tie(0);
int q;cin>>n>>q;
for(int i=2; i<=n; i++) {cin>>pa[i];ch[pa[i]].pb(i);}
int root=1;
dfs(root);
for(int i=0; i<2*n; i++){
if(-1==in[dfn[i]])in[dfn[i]]=i;
else out[dfn[i]]=i;
}
while(q--){
int det;cin>>det;
if(det==1){
int a, b;cin>>a>>b;
int d=b;
//線段樹的modify指令被我inline了
for(int i=in[a]+2*n; i; i>>=1){
st[i]+=d;
}
for(int i=out[a]+2*n; i; i>>=1){
st[i]+=d;
}
}if(det==2){
int u;cin>>u;
int ans=query(in[u], out[u]+1)/2;
cout<<ans<<'\n';
}
}
}
}
最低共同祖先
Lowest Common Ancestor
int dep[maxn];
int anc[18][maxn];
// anc[i][j] 代表 j 的 2^i 倍祖先
// 紀錄到每一點的 2^17 倍祖先 (大於1e5)
void dfs(int n, int fa, int d) {
anc[0][n] = fa; // 一倍祖先就是父親
dep[n] = d;
for (int v : adj[n]) {
if (v != fa) dfs(v, n, d+1);
}
}
void setupLCA() {
dep[0] = -1;
dfs(1, 0, 0);
for (int i = 1; i < 18; i++) {
for (int j = 1; j <= n; j++) {
anc[i][j] = anc[i-1][anc[i-1][j]];
}
}
}
int lca(int a, int b){
if (dep[a] < dep[b]) swap(a, b);
for (int i = 17;i >= 0;i--) {
if (dep[anc[i][a]] >= dep[b]) {
a = anc[i][a];
}
}
if (a == b) return a;
for (int i = 17;i >= 0;i--) {
if (anc[i][a] != anc[i][b]) {
a = anc[i][a];
b = anc[i][b];
}
}
return anc[0][a];
}
int main() {
// 省略輸入圖
setupLCA();
while (q--) {
int u, v;
cin >> u >> v;
cout << lca(u, v) << endl;
}
}
1
2
3
4
5
6
7
8
9
10
11
order | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
vertex | 1 | 2 | 3 | 4 | 3 | 5 | 3 | 2 | 1 |
order | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
vertex | 6 | 7 | 6 | 8 | 9 | 8 | 6 | 1 | 10 |
order | 19 | 20 | 21 |
vertex | 11 | 10 | 1 |
希望我不會燒雞
#include<iostream>
#include<vector>
#include<algorithm>
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx,avx2")
using namespace std;
const int N=2e5+5;
int in[N],out[N],sz[N],nxt[N],par[N],vec[N],seg[4*N],dep[N];
vector<int> ord;
vector<vector<int> > graph;
int cnt=0;
void dfs_sz(int node,int parent){
sz[node]=1;
par[node]=parent;
if(node!=1) dep[node]=dep[parent]+1;
int szz=graph[node].size();
int mx=0;
for(int i=0;i<szz;i++){
if(graph[node][i]==parent) continue;
dfs_sz(graph[node][i],node);
sz[node]+=sz[graph[node][i]];
if(sz[graph[node][i]]>mx){
mx=sz[graph[node][i]];
swap(graph[node][i],graph[node][0]);
}
}
}
void dfs_nxt(int node,int parent){
in[node]=++cnt;
ord.push_back(node);
for(auto x:graph[node]){
if(x==parent) continue;
if(x==graph[node][0]) nxt[x]=nxt[node];
else nxt[x]=x;
dfs_nxt(x,node);
}
out[node]=cnt;
}
void build(int l,int r,int ind){
if(l==r){
seg[ind]=vec[ord[l]];
}
else{
int mid=(l+r)>>1;
build(l,mid,ind*2);
build(mid+1,r,ind*2+1);
seg[ind]=max(seg[ind*2],seg[ind*2+1]);
}
}
void modify(int l,int r,int num,int pos,int ind){
if(l==r){
seg[ind]=num;
return;
}
int mid=(l+r)>>1;
if(pos<=mid) modify(l,mid,num,pos,ind*2);
else modify(mid+1,r,num,pos,ind*2+1);
seg[ind]=max(seg[ind*2],seg[ind*2+1]);
}
int query(int l,int r,int start,int end,int ind){
if(r<start||end<l) return 0;
if(start<=l&&r<=end) return seg[ind];
int mid=(l+r)>>1;
return max(query(l,mid,start,end,ind*2),query(mid+1,r,start,end,ind*2+1));
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int n,q;
cin>>n>>q;
graph.resize(n+1);
nxt[1]=1;
dep[1]=1;
ord.push_back(0);
int a,b;
for(int i=1;i<=n;i++) cin>>vec[i];
for(int i=1;i<n;i++){
cin>>a>>b;
graph[a].push_back(b);
graph[b].push_back(a);
}
dfs_sz(1,0);
dfs_nxt(1,0);
build(1,n,1);
int op;
for(int i=0;i<q;i++){
cin>>op;
if(op==1){
cin>>a>>b;
modify(1,n,b,in[a],1);
vec[a]=b;
}
else{
cin>>a>>b;
int ans=vec[a];
while(nxt[a]!=nxt[b]){
if(dep[nxt[a]]<dep[nxt[b]]) swap(a,b);
ans=max(ans,query(1,n,in[nxt[a]],in[a],1));
a=par[nxt[a]];
}
if(dep[a]<dep[b]) swap(a,b);
ans=max(ans,query(1,n,in[b],in[a],1));
cout<<ans<<" ";
}
}
}
過幾天大概會發公告講規則
By cjtsai
樹們