&& revised 9.15 9.16 simulation game

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;
} 
View Code

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;
} 
View Code

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;
}
View Code

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;
}
View Code

9.15

T1:考场上暴力解了excrt 然后求了方案数 大致是nlogn的复杂度 然后 考试快结束的时候 我的电脑系统自己把自己删掉了 比较nb把 我就不放考场代码了;

最后 这是个结论题 我丢 我太难了; 

不妨复习一下exgcd相关的知识 我的数学比较垃圾qwq; 

Guess you like

Origin www.cnblogs.com/Tyouchie/p/11541244.html