Tumor CSP-S rematch 2019 post-match summary

Preface

After the improvement group, I almost cried.

I personally watched the folk data with 300+ others, AC got three questions, and I got 200-, which broke three questions. .

Especially after looking at the scores on the evaluation, a 2h+ sweat-and-sweat test burst to zero. .

(Dirt dirty). . . . .

Day1

Note that this blog post is a summary of the competition and may not have a solution

Gray code

This question is relatively simple, just push it backwards according to the meaning of the question, the difficulty lies in its data range

It can be seen from the question that k<2^64 does not work with long long. If you still want to store directly, you can only use unsigned long long, and you must use it with trepidation.

Bracket tree

According to the meaning of the title, there are two kinds of reasonable bracket strings (set a capital letter as a reasonable bracket string):

  1. A=(B)
  2. A=B_{1}B_{2}...B_{n}

Two strings means two calculation methods, the first one, numA=numB+1, the second one,numA=\sum_{i=1}^{n}numB_{i} + n*(n-1)/2

It is easy to think of using a structure to represent a bracket string (sum sum, the number of items n), and then use the stack to store all the separated bracket strings on the path to the root node (with an unreasonable string that does not contain a reasonable string Separation, such as "("), the separated strings are only calculated separately and are not related to each other.

When the parenthesis of a node enters the judgment stack (at least there is a stack to judge it is reasonable) and matches the previous parenthesis, it needs to be discussed in categories:

  1. Two parentheses are adjacent to "()", directly stored in the big stack (sum=1, n=1);
  2. Non-adjacent "(...)", some reasonable strings are eliminated in the middle. Obviously, these strings must be connected together, and they are the top strings of the separated stack in the big stack. Take it out, change it (recalculate sum, n becomes 1) and put it in.

Before putting it on the stack, we need to make a special judgment: after the two parentheses are matched, it may cause two reasonable strings that were originally separated to become adjacent (such as " () ( () " plus one " ) ", After the above operations, it becomes " () (()) ", the red and green strings are adjacent, and should be combined into the second type of bracket string), at this time, the top of the stack must be kicked out and the string that will be entered is merged, and then put on the stack .

When calculating the value of each node in this way, backtracking should also be considered.

Because one path must be searched for another path after searching, the two stacks must be restored.

Can the reduction be directly assigned to a large structure?

No way! I deducted 50 because I was like this

Since the judgment stack either puts a parenthesis or enters a parenthesis every time, only the operation type and the changed value are recorded;

In the big stack, before a new string is pushed into the stack, either unchanged, or kicked one string, or kicked two strings, record the kicked strings (up to two) and restore them.

Time complexity is about O(n)

#include<cstdio>//整篇博客光秃秃,拼个代码丰富一下内容
#include<cstring>//大佬的代码60行,我的行数为两倍
#include<iostream>
#include<algorithm>
#include<vector>
#include<cmath>
#include<stack>
#define M 500005
#define ll long long
using namespace std;
int n,fa[M];
ll k[M];
vector<int>G[M];
bool c[M],spcl;
char s;
stack<int>st1;
inline int Read(){
    int x=0;char s=getchar();
    while(s<'0'||s>'9'){s=getchar();}
    while(s>='0'&&s<='9'){x=(x<<1)+(x<<3)+s-'0';s=getchar();}
    return x;
}
struct itn{
    int l,r;
    ll NUM,SUM;
    itn(){l=r=NUM=SUM=0;}
    itn(int L,int R){
        l=L,r=R;
    }
};
struct bol{
    stack<itn>S;
    ll ans;
}st2;
void dfs(int x){
    itn yst1,yst2;
    if(!st2.S.empty())yst1=st2.S.top();
    if(st2.S.size()>1){
        st2.S.pop();yst2=st2.S.top();
        st2.S.push(yst1);
    }
    ll rt=st2.S.size(),yan=st2.ans;
    int out=-1,jin=-1;
    if(st1.empty()||c[st1.top()]==c[x]){
        st1.push(x);
        jin=1;
        k[x]=k[fa[x]];
    }
    else{
        if(c[st1.top()]==0){
            int l=st1.top();
            itn in=itn(l,x);
            st1.pop();
            out=l;
            if(l!=fa[x]){
                itn A=st2.S.top();
                st2.S.pop(),st2.ans-=A.SUM+1ll*(A.NUM*(A.NUM-1ll)>>1);
                in.NUM=1ll,in.SUM=1ll+(A.SUM+1ll*(A.NUM*(A.NUM-1ll)>>1));
            }
            else{
                in.NUM=1ll,in.SUM=1ll;
            }
            if(st2.S.empty()||st2.S.top().r!=fa[l]){
                st2.S.push(in);
                st2.ans+=in.SUM+1ll*(in.NUM*(in.NUM-1ll)>>1);
            }
            else{
                itn A=st2.S.top();
                st2.S.pop(),st2.ans-=A.SUM+1ll*(A.NUM*(A.NUM-1ll)>>1);
                A.r=x,A.NUM+=in.NUM,A.SUM+=in.SUM;
                st2.S.push(A);
                st2.ans+=A.SUM+1ll*(A.NUM*(A.NUM-1ll)>>1);
            }
            k[x]=st2.ans;
        }
        else{
            st1.push(x);
            jin=1;
            k[x]=k[fa[x]];
        }
    }
    for(int i=0;i<G[x].size();i++){
        dfs(G[x][i]);
    }
    if(spcl){
        if(jin>0)st1.pop();
        if(out>0)st1.push(out);
        while(st2.S.size()>rt)st2.S.pop();
        if(yst2.l>0){
            while(st2.S.size()>rt-2)st2.S.pop();
            st2.S.push(yst2),st2.S.push(yst1);
        }
        else{
            if(yst1.l>0){
                while(st2.S.size()>rt-1)st2.S.pop();
                st2.S.push(yst1);
            }
        }
        st2.ans=yan;
    }
}
int main()
{
    //freopen("brackets.in","r",stdin);
    //freopen("brackets.out","w",stdout);
    n=Read();
    for(int i=1;i<=n;i++){
        s=getchar();
        while(s!='('&&s!=')')s=getchar();
        c[i]=(s==')');
    }
    for(int i=2;i<=n;i++){
        fa[i]=Read();
        if(fa[i]!=i-1)spcl=1;
        G[fa[i]].push_back(i);
    }
    dfs(1);
    ll ans=k[1];
    for(ll i=2;i<=1ll*n;i++)ans^=(i*k[i]);
    printf("%lld\n",ans);
    return 0;
}

Number on tree

I haven't figured it out yet, I only cut a PPT

Day2

Emiya’s meal today

This is my blood and sweat problem

&%&…@%#@%¥%#(*#*&@T@(#*#^$*#(FUCK)#(*&$^&#^%*&&@#...

Seeing this question, I thought of Rongju, and also thought of dp style... as if seeing the dawn of cheating 84 points...

But the formula is wrong, more than 100 lines of code, the compiler can't adjust it, and finally it can't be checked...

I am too obsessed with this question, the strategy is seriously wrong

Ugh. . .

Division, the center of gravity of the tree

Although these two questions are difficult, people with brains should be able to deceive a score of 100+ (except for AK bosses)

As long as people get partial credit, score will also zero positive solutions than those explosive knock of death (like me) is much higher

to sum up

After thinking about the painful lessons, I deeply realized that, except for the big guys in the AK abuse field, violent deception is the key trick for our little ju to get the first one. The key choice, the decisive factor, and the only way!

Don’t think you can play AC if you have an idea (except for the big guys)

The basic skills of violent deception and optimization (and hand speed) must be practiced to the extreme!

Guess you like

Origin blog.csdn.net/weixin_43960287/article/details/103140857