20,190,821 exam.

Prediction: 100 + 30 + (10/20) = 140 / 150. Actual: 10 + 30 + 30 = 70.

T1: Summer vacation, small P is planning his vacation leave little P ready to go to the gym, but the gym or watching movies and cinemas are likely to not open that day so there every day in the state 4, we used 0,1,2... 3 indicates .0: Stadium and cinemas were closed; 1: stadium closed, open cinema; 2: open gym, cinema closed; 3: stadiums and movie theaters are open to small P did not want a day without anything to do not want continuous two days to do the same thing, now you arrange vacation plans for small P, did not meet the number of days in the two days doing the same thing while minimizing small P nothing to do.

S1: look at a, 2-sat not immediately thought of DP, with f [i] [1/2], represents the state of the first day i was i, the maximum number of days before i can play day state?.. g [i] points g [i] = 0/1/2/3 to be discussed separately .①g [i] = time 1, f [i] [1] = max {f [i-1] [2] +1} , f [i] [2] = f [i -1] [2] .②g [i] = 2, f [i] [2] = max {f [i -1] [1] +1}, f [i] [1] = f [i -1] [1] .③g [i] = 3, is combined ①② .④g [i] = 4, f [i] [1] = f [i - 1] [ 1], f [i] [2] = f [i - 1] [2] complete test sample after sample finished playing with the hand that WA a final sound of a lot of research, own number of days. do not choose the f [i] [0] state simply did not design?! ​​this is not careful thinking of the consequences, lost 90 points! after the last exchange with sy chiefs, found that f [i] [0/1/2] representation before i break of day, dp equation is obvious.

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
#define e exit(0)
#define re register
#define inf 19260817
int n,ans,f[1000010][3],g[1000010];
int main()
{
    freopen("vocation.in","r",stdin);
    freopen("vocation.out","w",stdout);
    scanf("%d",&n);
    for(re int i=1;i<=n;++i){
        scanf("%d",&g[i]);
        f[i][1]=f[i][2]=inf;
    }
    for(re int i=1;i<=n;++i){
        f[i][0]=min(f[i-1][0],min(f[i-1][1],f[i-1][2]))+1;
        if(g[i]==1||g[i]==3)
            f[i][1]=min(f[i-1][0],f[i-1][2]);
        if(g[i]==2||g[i]==3)
            f[i][2]=min(f[i-1][0],f[i-1][1]);
    }
    printf("%d",min(f[n][0],min(f[n][1],f[n][2])));
    return 0;
}

T2: Small P After completing the tree structure, the center of gravity of the tree is known to be an interest in a tree, a node is the center of gravity of the tree, to meet the size of all blocks formed after Unicom will not remove this node. More than half the size of the entire tree. prove the existence of a center of gravity of a certain tree, and there are a maximum of two focus now small P want to know, in a given tree is the root, each of them ask subtree which are the focus point .

S2: the center of gravity of the tree bare title played only two special cases of the process we first multiplier array tree, the tree traversal process dfs in the size [x], maxx [x] (x is in the root. subtree maximum size). for each point doubling we find maxx [x] <= size limit of fa [fa] / 2, and then the size [x]> = size [fa] / 2 to find fa the upper limit on this range matching fa, ans [fa] = x.

Details: ①if (! Pos = x) pos = fa [pos], in fact, you can refer to lca multiplication problem to take the final step father's.

    ②size [x] * 2> = size [fa]. In fact, is to limit the other side of the link block size is smaller than size [fa] / 2.

    ③maxx array action actually is cut after its subtrees x Unicom size of the largest block.

 

#include<iostream>
#include<cstdio>
using namespace std;
#define re register
const int maxn=1e6+10;
int n,id,cnt,fa[maxn],size[maxn],maxx[maxn],head[maxn],ans[maxn],bz[maxn][24];
struct bian{
    int to,next;
}len[maxn<<1];
void add(int from,int to)
{
    len[++cnt].to=to;
    len[cnt].next=head[from];
    head[from]=cnt;
}
void dfs(int x)
{
    size[x]=1;
    for(re int k=head[x];k;k=len[k].next){
        int to=len[k].to;
        dfs(to);
        size[x]+=size[to];
        maxx[x]=max(maxx[x],size[to]);
    }
}
void work(int x)
{
    int pos=x;
    for(re int i=20;i>=0;--i)
        if(bz[pos][i]&&maxx[x]*2-size[bz[pos][i]]>0)
            pos=bz[pos][i];
    if(pos!=x) pos=fa[pos];
    while(pos&&size[x]*2-size[pos]>=0){
        if(maxx[x]*2-size[pos]<=0) ans[pos]=x;
        pos=fa[pos];
    }
    for(re int k=head[x];k;k=len[k].next){
        int to=len[k].to;
        work(to);
    }
}
int main()
{
    freopen("tree.in","r",stdin);
    freopen("tree.out","w",stdout);
    scanf("%d%d",&n,&id);
    for(re int i=2;i<=n;++i){
        scanf("%d",&fa[i]);
        bz[i][0]=fa[i];
        add(fa[i],i);1
    Dfs (
    });
    for(re int j=1;j<=20;++j)
        for(re int i=1;i<=n;++i)
            bz[i][j]=bz[bz[i][j-1]][j-1];
    work(1);
    for(re int i=1;i<=n;++i)
        printf("%d\n",ans[i]);
}

 

T3: P favorite small array data structure of the magic, so he got three arrays of length n, a, b, c because of the small US-P like simple, so he decides to keep only a prefix for each array. . Suppose three small array prefix length P are retained u, v, w (0 ≤ u, v, w ≤ n), in order to ensure completeness of the array, the need to ensure small P prefix which contains all three of the original array elements, and u + v + minimum w. now you tell smallest of the small P u + v + w is the number?

S3: with a map to fight fake greedy yet there are 30 first cuckoo.

 

Guess you like

Origin www.cnblogs.com/xqysckt/p/11390940.html