CSP-S 2019 portion explanations

D1T1- Gray code

Title given method of constructing a Gray code.

$ Solve (n, k) $ express obtain rankings under $ ^ n $ 2 to $ k $ significance of the Gray code,

Consider only to compare the value of the highest bit like 0/1.

To open sub-section suggests $ unsigned \ long \ long $, pay attention to it.

 

 

 

D1T2- brackets tree

Subsequence problem is to facilitate the process, as long as the processing sequence of a legitimate end of each point, and the like as a prefix tree.

However legitimate brackets sequences also not simple.

Analyzing a bracket sequence legal method is

Depending on the left and right parentheses are + 1, -1.

And judges whether the prefix is ​​not less than 0, and the sum is zero.

Apply this idea, a thought on the practice exam Yes.

Multiset with a prefix and maintenance.

Insert element when a left parenthesis is added, at the same time to set all the elements for processing a plus.

When a right parenthesis is added continuously remove the smallest element in the set, i.e., the prefix is ​​not less than zero is determined valid.

While maintaining a barrel record set of elements in the tree and prefix, this can be done O (1) direct access to legitimate the current point to the end of the sequence in parentheses.

However, because of the special nature of the tree, SET need to restore, in the worst case (Fig may broom), this algorithm may be the card to O (n ^ 2logn).

Because official data is water, it is the AC. Because Luo Gu data is water, it is the AC.

Because cattle passenger data and school data are not clear north water, it TLE80 points.

Positive solutions actually use another way to generate a legitimate point to the end of the sequence of brackets, which also prompted the title background.

Find the nearest one to meet left parenthesis number equal to the number of points the right parenthesis, to meet the legal significance under this section, as long as it is a plus point for the legal front brackets ending sequence number generated just fine.

A simple approach is to use the stack to maintain, left parenthesis that is pushed onto the stack, right parenthesis that is pop the top element, and can determine the first legal position.

 

 

 

Number D1T3- tree

Probably a greedy.

I want to change a point to point to the desired change, limiting a switching order of each point on the path.

Looks very then partially divided to play, as long as the maintenance of the right and left chain sequence, as long as the daisy and check out a similar structure to set the inserted sequence determined.

Category talk then feeling very complex, both did not play out, only 10 minutes violence.

This question has not changed.

 

 

 

D2T1-Emiya family meal today

This question has not started thinking, feeling not quite do.

Guess complexity, estimated to be $ O (n ^ 2m) $, so to enumerate dish?

Then suddenly thought, this stuff is simply the inclusion-exclusion just fine.

The final enumeration which is not lawful dish Road.

A simple approach is to directly record a selected number of dishes and choose how much illegal road course, the complexity of such direct $ dp $ is $ (n ^ 3m) O $.

However much the number of states, so it is conceivable that the differences are recorded, that is, the number of illegal dishes - dishes selected number / 2, while maintaining the parity of the number of dishes chosen,

Then the complexity on the right, and then did not play because modulo optimization success is often a card.

 

 

 

D2T2- division

See the whole range of data ignorant, and do not have any ideas.

Violence then found $ dp $, $ O (n ^ 2) $ had 64 points, so a direct hit.

$ Dp (l, r) $ represents the last selected interval, is clearly a transition point suffix,

As long as the pre-monotonous suffix pointer position, direct access to the minimum suffix like.

There is a positive solution greedy, as long as the minimum interval of the last election, the answer is minimal.

It does not prove, however, an intuitive understanding of what is right.

Set $ ​​f_x $ $ x $ represents the end of the minimum of the last selected range, there is a simple transfer

$ F_i = min_j (pre_i-pre_j) (pre_i-pre_j> = f_j) $, form of this stuff quite simple,

Incidentally record what the answer is to do $ O (n ^ 2) $, and mentally pruning is to find the first answer directly out at some of the more water can get 84 data points.

And then found that the transfer $ pre_i-pre_j> = f_j $, i.e. $ pre_i> = f_j + pre_j $, $ pre $ array as monotonous, it is clear that the transfer point is monotonous.

Then with a monotonous queue maintains about enough.

Because the data is too large, need to write high precision.

In order to prevent $ MLE $, it can not record the answers but at the same time maintain the transfer of the transfer point.

The last statistics about the answer just fine.

 

 

 

Focus D2T3- tree

Look question found that some 75 points, but played just fine.

Violence and chain can play directly.

For full binary tree, make a table to find an answer only in the root node and its two sons coefficient is a power of 2, all other nodes coefficient 1.

Exam final minutes probably think the answer must appear only on the heavy chain.

So heavy maintenance, while half of the answer can, of course, relatively simple approach is to use multiplication process to achieve this dichotomy.

然而并不会维护父亲方向的重链,实际上是一个简单的换根$dp$,难度并不是很大。

在计算的过程中多打几个特判就好了。

#include<bits/stdc++.h>
using namespace std;
const int N=3e5+7;
int n,tot=1;
int head[N],nxt[N<<1],to[N<<1];
int sz[N],son[N],son2[N];
int f[N][20];
long long ans;
void dfs1(int x,int fa){
    sz[x]=1;
    for(int i=head[x];i;i=nxt[i]) if(to[i]!=fa){
        dfs1(to[i],x);
        sz[x]+=sz[to[i]];
        if(sz[to[i]]>sz[son[x]]) son2[x]=son[x],son[x]=to[i];
        else if(sz[to[i]]>sz[son2[x]]) son2[x]=to[i];
    }
    f[x][0]=son[x];
    for(int i=1;i<=18;++i) f[x][i]=f[f[x][i-1]][i-1];
}
int solve(int x){
    if(!son[x]) return x;
    int now=x,ans=0;
    for(int i=18;~i;--i) if(sz[x]-sz[f[now][i]]<sz[x]/2) now=f[now][i];
    if(sz[son[now]]<=sz[x]/2&&sz[x]-sz[now]<=sz[x]/2) ans+=now;
    now=son[now];
    if(sz[son[now]]<=sz[x]/2&&sz[x]-sz[now]<=sz[x]/2) ans+=now;
    return ans;
}
void dfs2(int x,int fa){
    for(int i=head[x];i;i=nxt[i]) if(to[i]!=fa){
        int tmp=son[x],s=sz[x];
        sz[x]=n-sz[to[i]];
        if(to[i]==son[x]) son[x]=son2[x];
        if(fa&&sz[fa]>sz[son[x]]) son[x]=fa;
        f[x][0]=son[x];
        for(int j=1;j<=18;++j) f[x][j]=f[f[x][j-1]][j-1];
        ans+=solve(to[i]);
        ans+=solve(x);
        dfs2(to[i],x);
        son[x]=tmp; sz[x]=s; f[x][0]=son[x];
        for(int j=1;j<=18;++j) f[x][j]=f[f[x][j-1]][j-1];
    }
}
inline void add(int a,int b){
    nxt[++tot]=head[a]; to[head[a]=tot]=b;
    nxt[++tot]=head[b]; to[head[b]=tot]=a;
}
inline int read(register int x=0,register char ch=getchar(),register int f=0){
    for(;!isdigit(ch);ch=getchar()) f=ch=='-';
    for(; isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+(ch^48);
    return f?-x:x;
}
int main(){
    freopen("centroid.in","r",stdin);
    freopen("centroid.out","w",stdout);
    int T=read();
    while(T--){
        tot=1; ans=0;
        memset(head,0,sizeof(head));
        memset(son,0,sizeof(son));
        memset(son2,0,sizeof(son2));
        n=read();
        for(int i=1;i<n;++i) add(read(),read());
        dfs1(1,0); dfs2(1,0);
        printf("%lld\n",ans);
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/skyh/p/11953978.html