B. On tree chain
Title:
Given a tree T, each point on the tree T has a weight.
Define the size of the sub chain of a tree as: the sum of the weights of all nodes in the sub chain.
Please find the largest sub chain in tree T and output.
Train of thought:
It is similar to the tree dp to find the diameter of the tree.
d(i) represents the maximum distance from point i to any point of a subtree with i as its root
In the process of dfs, we record the largest and the next largest sub trees.
1. If the longest chain does not pass through the edge of the parent node, the largest and the second largest links are the longest chains passing through the current point.
2. If the longest chain passes through the edge of the parent node, then the correct longest chain can be calculated when going back to the parent node.
So it is not incomplete to ignore the parent node.
code:
#include<bits/stdc++.h> using namespace std; #define int long long const int maxm=1e5+5; vector<int>g[maxm]; int a[maxm]; int d[maxm]; int ans=-1e18;//Because of the negative point weight, ans should be initialized to - inf void dfs(int x,int fa){ int t1=0,t2=0;//t1,t2 record the maximum and the second largest for(int v:g[x]){ if(v==fa)continue; dfs(v,x); if(d[v]>t1){ t2=t1; t1=d[v]; }else if(d[v]>t2){ t2=d[v]; } } d[x]=t1+a[x]; ans=max(ans,t1+t2+a[x]); } signed main(){ int n; cin>>n; for(int i=1;i<=n;i++){ cin>>a[i]; } for(int i=1;i<n;i++){ int a,b; cin>>a>>b; g[a].push_back(b); g[b].push_back(a); } dfs(1,-1); cout<<ans<<endl; return 0; }
C. Exchange game
Title:
Give a string of length 12 containing only o and -
One operation is to change the substring o o - in the string to - O
One operation is to change the substring o o in the string to o –
Ask the minimum o in the string after infinite operations
Train of thought:
After each operation, a new sequence will be obtained, and then the minimum value of the new sequence will be calculated.
Therefore, it can be found that the minimum value of the original string is the minimum value of all new strings that can be obtained in one step.
The minimum value of the new string obtained by one step operation is the minimum value of the new string Therefore, the memory search can take min.
Because the length of the string is only 12, it can be compressed into binary string, which is convenient for operation.
code:
#include<bits/stdc++.h> using namespace std; const int maxm=1<<12; bool mark[maxm]; int ans[maxm]; void solve(int x){ if(mark[x])return ; mark[x]=1; for(int j=0;j<12;j++)ans[x]+=(x>>j&1);//Initialize the number of answers to 1 for(int k=2;k<12;k++){ int i=k-2,j=k-1; if((x>>i&1)&&(x>>j&1)&&!(x>>k&1)){//oo- int temp=x-(1<<i)-(1<<j)+(1<<k); solve(temp); ans[x]=min(ans[x],ans[temp]); }else if(!(x>>i&1)&&(x>>j&1)&&(x>>k&1)){//-oo int temp=x+(1<<i)-(1<<j)-(1<<k); solve(temp); ans[x]=min(ans[x],ans[temp]); } } } signed main(){ for(int i=0;i<(1<<12);i++)solve(i);//Direct pretreatment of all cases int T; cin>>T; while(T--){ string s; cin>>s; int x=0; for(int j=0;j<12;j++){ if(s[j]=='o'){ x|=(1<<j); } } cout<<ans[x]<<endl; } return 0; }
H. Type of goods
Title:
Give n and m for n barns and M operations
For each operation (L,R,d), it means that the granary of bar section [L,R] is filled with cargo D
That barn has the most cargo after m operations
n<=1e5,m<=1e5,d<=1e9
Train of thought:
The difference is almost the same as the difference of simple number addition and subtraction.
The difference only lies in that each position may add or reduce multiple numbers, which cannot be operated directly like the addition and subtraction method.
You need to open two arrays to store the number to be added or decreased for each position.
See code for details.
code:
#include<bits/stdc++.h> using namespace std; const int maxm=1e5+5; vector<int>add[maxm];//Add to vector<int>del[maxm];//reduce map<int,int>mark;//Record the number of occurrences of each number signed main(){ int n,m; cin>>n>>m; for(int i=1;i<=m;i++){ int l,r,d; cin>>l>>r>>d; add[l].push_back(d); del[r+1].push_back(d); } int ans=0; int ma=0; int now=0; for(int i=1;i<=n;i++){ for(int v:add[i]){ mark[v]++; if(mark[v]==1)now++; } for(int v:del[i]){ mark[v]--; if(mark[v]==0)now--; } if(now>ma){ ma=now; ans=i; } } cout<<ans<<endl; return 0; }