The revised 9.16 to 9.15 of match because playing computer games when the collapse of the then gg;
9.16 Tl: Title effect: Given a tree, for n nodes each node has a weight value (1 or 0), selecting a communication sub-block, so that the number of the communicating block number 0 and 1 the maximum absolute value of the difference;
Then listen to chdy chiefs say this is a routine topic so I learned about changing root and secondary scanning dp;
There is a general topic of this model: Given a tree, we need to each point as a whole pieces of tree root statistical answer; common way is to do it through two scans, drop by the complexity of the (n ^ 2) of to (n-);
1. arbitrarily designated as a root node, and then once dfs, from the bottom up, back when statistics answer the first time scanning;
2. The second scan time of departure from the earlier elected root, once dfs, down the answer after the update from the root of the change;
https://www.acwing.com/problem/content/289/;
Advanced algorithms from the title race with a guide to introduce secondary scanning root of change;
Then for this topic is a adventitious roots of a tree dp practice we have a practice n ^ 2 for each node once the maximum flow rate as a statistical dfs root, then max; consider (n) approach;
The maximum flow rate in accordance with the above procedure we may choose to No. 1 as the root node of the entire tree, each node i figured out his son as the root of the tree when the d [x], is clearly a dp we can do it;
Then we consider each node as the root of the whole tree approach; set F [x] x represented as a tree root whole pieces of answer, obviously we know f [1] = d [1];
When f [x] has been seeking out, considering its child node y, for F [y] contains two parts:
1. For the y maximum flow inside the root subtree, i.e. D [y];
2. For the y-flow beyond his internal subtree, and go up along x;
For the above that subject, when x as the source point, the flow rate of F [x] We know y from the x-flowing traffic should be min (flow (x, y) , d [y]), so that from outside the x flowing y node the flow is the difference between the two;
So we y as the root of the whole tree when we can start flowing y x, apparently f [y] = d [y ] + min (f [x] -min (flow (x, y), d [y ]), flow (x, y ));
f [x] -min (flow (x, y), d [y]) refers to that branch in addition to other than the x of y, for the other point of maximum flow;
I actually first pass and did not take into account whether the circumstances of the leaves, but this approach is only one strand or two times, three points is wrong;
So when the leaves when x, F [Y] = D [Y] + Flow (x, Y);
#include<bits/stdc++.h> using namespace std; const int N=210010; template<typename T>inline void read(T &x) { x=0;T f=1,ch=getchar(); while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} x*=f; } int T,n,m,tot,x,y,v,ans,lin[N],d[N],f[N],du[N]; struct gg { int y,next,v; }a[N<<1]; inline void add(int x,int y,int v) { a[++tot].y=y; a[tot].next=lin[x]; lin[x]=tot; a[tot].v=v; } inline void dp(int x,int fa) { d[x]=0; for(int i=lin[x];i;i=a[i].next) { int y=a[i].y; int v=a[i].v; if(y==fa) continue; dp(y,x); if(du[y]==1) d[x]+=v; else d[x]+=min(d[y],v); } return; } inline void dfs(int x,int fa) { for(int i=lin[x];i;i=a[i].next) { int y=a[i].y; if(y==fa) continue; if(du[x]==1) f[y]=d[y]+a[i].v; if(du[x]>1) f[y]=d[y]+min(f[x]-min(a[i].v,d[y]),a[i].v); dfs(y,x); } } int main() { //freopen("1.in","r",stdin); read(T); while(T--) { read(n); tot=0; memset(du,0,sizeof(du)); memset(d,0,sizeof(d)); memset(lin,0,sizeof(lin)); memset(f,0,sizeof(f)); for(int i=1;i<n;i++) { read(x); read(y); read(v); add(x,y,v); add(y,x,v); ++du[x]; ++du[y]; } dp(1,0); f[1]=d[1]; dfs(1,0); ans=0; for(int i=1;i<=n;i++) { ans=max(ans,f[i]); } cout<<ans<<endl; } return 0; }
We just now apparent that the subject can change dp + tree root solution, we have f [i] i is represented internally in the subtree rooted at the maximum value G [i] [represented by whole pieces as the root tree is a comparative examination regret but the thought did not dare write;
#include<bits/stdc++.h> using namespace std; template<typename T>inline void read(T &x) { x=0;T f=1,ch=getchar(); while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} x*=f; } const int N=1000010; struct gg { int y,next; }a[N<<1]; int n,m,x,y,w[N],lin[N],tot,f[N],g[N],mark[N],ans=-(1<<30); inline void add(int x,int y) { a[++tot].y=y; a[tot].next=lin[x]; lin[x]=tot; } inline void dp(int x,int fa) { f[x]=w[x]; for(int i=lin[x];i;i=a[i].next) { int y=a[i].y; if(y==fa) continue; dp(y,x); if(f[y]>0) { f[x]+=f[y]; mark[y]=1; } } } inline void dfs(int x,int fa) { for(int i=lin[x];i;i=a[i].next) { int y=a[i].y; if(y==fa) continue; if(mark[y]) g[y]=max(f[y],g[x]-f[y]); else g[y]=max(0,g[x])+f[y]; dp(y,x); } } int main() { read(n); int flag=0; for(int i=1;i<=n;i++) { read(w[i]); w[i]=w[i]==1?1:-1; if(i>1) if(w[i]!=w[i-1]) flag=1; } for(int i=1;i<n;i++) { read(x); read(y); add(x,y); add(y,x); } if(!flag) { cout<<n<<endl; return 0; } dp(1,0); g[1]=f[1]; dfs(1,0); for(int i=1;i<=n;i++) { ans=max(ans,g[i]); w[i]=-w[i]; mark[i]=g[i]=f[i]=0; } dp(1,0); g[1]=f[1]; dfs(1,0); for(int i=1;i<=n;i++) ans=max(ans,g[i]); cout<<ans<<endl; return 0; }
Then there is a solution to a problem on the comparison, an ingenious idea, then the subtree directly maintain the maximum difference value; the point 0 as -1, i.e. maintains a positive maximum value to maintain a negative minimum value so that the absolute value a case where the maximum value;
#include<bits/stdc++.h> using namespace std; template<typename T>inline void read(T &x) { x=0;T f=1,ch=getchar(); while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} x*=f; } const int N=110000; int n,m,x,y,tot,a[N],lin[N],f[N],g[N]; struct gg { int y,next; }e[N<<1]; inline void add(int x,int y) { e[++tot].y=y; e[tot].next=lin[x]; lin[x]=tot; } inline void dfs(int x,int fa) { g[x]=f[x]=a[x]; for(int i=lin[x];i;i=e[i].next) { int y=e[i].y; if(y==fa) continue; dfs(y,x); f[x]+=max(0,f[y]); g[x]+=min(0,g[y]); } } int main() { freopen("trip.in","r",stdin); freopen("trip,out","w",stdout); read(n); for(int i=1;i<=n;i++) { read(a[i]); a[i]=a[i]==0?-1:a[i]; } for(int i=1;i<n;i++) { read(x); read(y); add(x,y); add(y,x); } dfs(1,1); int ans=0; for(int i=1;i<=n;i++) { ans=max(ans,f[i]); ans=max(ans,-g[i]); } cout<<ans<<endl; return 0; }
T2 yesterday Liu God never studied mathematics D hhh
Title effect: Given n, m, ask how many characters are set to meet the size of the string prefix length m is greater than 1, n is palindromic sequence only.
I started the whole thing wrong recursive all wrong qwq;
That is the first consideration of all palindromic number is the number of strings: The obvious answer is m n / 2-th power;
Now I bb I had the wrong idea: For a palindrome string Obviously we consider only the half of it so his remaining n / 2 positions then there are m candidate set number of elected if you do not want each this is obviously the same number of permutations of A (m, n / 2);
But I was elected I would now like to consider the same numbers .... how do I wish to expand the alternative set of n / 2 times each number can not be elected repeatedly Well looked good for ah
In fact, your original set is {1,2,3, ..., m} after expanding your ideal state is {1,2,3, ..., m, 1,2,3, ..., m , ....., m} of course set so that even then having reciprocity 1 have been chosen, but a plurality of them are essentially different from the number might be understood
Now 1 1, 1 2, ... 1 m, has a different nature so obviously we figure it out for a number of statistics he would be many times as different cases are accumulated so wrong;
Well, that does not look at my mistake thinking that we have to consider seeking out all the palindromic sequence number considering how demand without lawful;
That is, we set f (i) represents the current i and the length of palindromic sequence number satisfies the conditions, we can find a recursion formula;
F (n-) m = n-/ 2 -sigma I <. 4 / NF (I) * m (2 * n--I) / 2 , then is a little puzzling recursive solution of the above problem somewhat different; the following qwq not quite understand when the evening discussion in the Well;
I still say to me that equation we consider prefix and optimize it, you can (n) complexity of the; // array of small open
#include<bits/stdc++.h> using namespace std; typedef long long ll; template<typename T>inline void read(T &x) { x=0;T f=1,ch=getchar(); while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} x*=f; } const int mod=1e9+7; const int N=110000; int n,m,pw[N],f[N]; int g[N];//前缀和数组; inline int pop(int a,int b){a-=b;return a<0?a+mod:a;} inline int add(int a,int b){a+=b;return a>=mod?a-mod:a;} inline int mul(int a,int b){return (ll)a*b%mod;} int main() { freopen("string.in","r",stdin); freopen("string.out","w",stdout); read(n); read(m); pw[0]=1; for(int i=1;i<=n;i++) pw[i]=mul(pw[i-1],m); for(int i=1;i<=n;i++) { f[i]=pop(pw[(i+1)/2],g[(i+1)/2]); if(i>1) g[i]=add(f[i],mul(g[i-1],m));//对于处理这个点缀和; } cout<<f[n]<<endl; return 0; }
9.15
T1:考场上暴力解了excrt 然后求了方案数 大致是nlogn的复杂度 然后 考试快结束的时候 我的电脑系统自己把自己删掉了 比较nb把 我就不放考场代码了;
最后 这是个结论题 我丢 我太难了;
不妨复习一下exgcd相关的知识 我的数学比较垃圾qwq;