"The sub-entrance exam," the second week of three examinations


The exam feeling daze.
Beginning midday nap has not yet awake, and then fainted for about half an hour.
And then began to see the results of these questions ... the big problem is the article ...
I thought I could \ (A \) away \ (T3 \) , the results because the topics are reasons pit off \ (70pts \) ...
look this test can not be exam ...

T1 "JOISC 2016 Day 3" telegram

topic

click here

Examination room thinking

Stumbled, I did not think the code did not pay off ...

Correct

First, the time complexity of this problem is very friendly ...
look at the characteristics of this figure, it is found that ring tree .
The so-called tree ring group, there is \ (N \) points, \ (N \) edges (characteristic part) .
So, if we want to become a strong view of such a connected graph, a diagram illustrates this must be a big ring.
But know this does not seem to know how to do problems ...
this topic, does not seem to say how connected after these edges removed, then we need to consider how then Jieshangqu side.
So ... hey hey hey Guannameduo doing.
To this figure into a large ring, we first find out ring, will not be a point on the ring makes up a single strand.
How to do it?
Consider a node on the ring is not \ (U \) , its penetration \ (in [U] \) .
If \ (in [U]> 1 \) , then connect to \ (u \) range edges, leaving the most expensive, the rest are cut off, as to how then, this is not what we consider .. .
However, if \ (u \) in the ring, empathy, leaving the most expensive, the rest are cut off.
But there is a special place, one side of each ring must be cut off, otherwise there is no way they and the other ring or chain excel at a single big ring.
Implementation

#include<cstdio>
#include<cstdlib>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
#define int long long
#define rep(q,__a,__b) for(int q=__a,q##_end_=__b;q<=q##_end_;++q)
#define dep(q,__a,__b) for(int q=__a,q##_end_=__b;q>=q##_end_;--q)
template<class T>inline void qread(T& x){
    char c;bool f=false;x=0;
    while((c=getchar())<'0'||'9'<c)if(c=='-')f=true;
    for(x=(c^48);'0'<=(c=getchar())&&c<='9';x=(x<<1)+(x<<3)+(c^48));
    if(f)x=-x;
}
template<class T,class... Args>inline void qread(T& x,Args&... args){qread(x),qread(args...);}
inline int rqread(){
    char c;bool f=false;int x=0;
    while((c=getchar())<'0'||'9'<c)if(c=='-')f=true;
    for(x=(c^48);'0'<=(c=getchar())&&c<='9';x=(x<<1)+(x<<3)+(c^48));
    return f?-x:x;
}
template<class T>inline T Max(const T x,const T y){return x>y?x:y;}
template<class T>inline T Min(const T x,const T y){return x<y?x:y;}
template<class T>inline T fab(const T x){return x>0?x:-x;}
inline void getInv(int inv[],const int r,const int MOD)
{inv[0]=inv[1]=1;for(int i=2;i<=r;++i)inv[i]=1ll*inv[MOD%i]*(MOD-MOD/i)%MOD;}

const int MAXN=1e5;
const int INF=0x3f3f3f3f;

struct edge{
    int u,w;
    edge(){}
    edge(const int U,const int W):u(U),w(W){}
};
vector<edge>rG[MAXN+5];

int N,in[MAXN+5],fa[MAXN+5],ans,bel[MAXN+5],Ccnt,faw[MAXN+5],cirNode[MAXN+5];
bool vis[MAXN+5],broken[MAXN+5],flg;

inline void topo(){
    queue<int>Q;
    for(int i=1;i<=N;++i)if(in[i]==0)
        Q.push(i);
    if(Q.empty())flg=true;
    while(!Q.empty()){
        int now=Q.front();Q.pop();
        vis[now]=true,--in[fa[now]];
        if(in[fa[now]]==0)Q.push(fa[now]);
    }
    //处理属于哪个环
    for(int i=1,u;i<=N;++i)if(!vis[i]&&!bel[i]){//是环上点
        u=i,++Ccnt;
        cirNode[Ccnt]=i;
        while(bel[u]==0){
            bel[u]=Ccnt;
            u=fa[u];
        }
    }
    if(flg&&Ccnt==1)exit(0&puts("0"));
}

inline void init(){
    qread(N);
    for(int i=1;i<=N;++i){
        qread(fa[i],faw[i]);
        ++in[fa[i]];
        rG[fa[i]].push_back(edge(i,faw[i]));
    }
}

inline bool cmp(const edge a,const edge b){return a.w>b.w;}

inline void solvenode(){//处理入度多于 1 的点
    for(int i=1;i<=N;++i)if(rG[i].size()>1){
        sort(rG[i].begin(),rG[i].end(),cmp);
        for(int j=rG[i].size()-1;j>=1;--j){
            ans+=rG[i][j].w;
            if(bel[i]==bel[rG[i][j].u])broken[bel[i]]=true;
        }
    }
}

inline void breakcircle(){
    for(int i=1,j,k,mine;i<=Ccnt;++i)if(!broken[i]){//如果有环还没有被破开
        j=k=cirNode[i],mine=faw[j];
        do{
            // printf("Now k==%lld\n",k);
            if(rG[k].size()>1)mine=Min(mine,rG[k][0].w-rG[k][1].w);//可以保证,没有被删掉的边一定是环上边
            mine=Min(mine,faw[k]);
            k=fa[k];
        }while(k!=j);
        // printf("circle %lld:mine==%lld\n",i,mine);
        ans+=mine,broken[i]=true;
    }
}

signed main(){
    // freopen("04-20.in","r",stdin);
    init();
    topo();
    solvenode();
    // printf("After node:ans==%lld\n",ans);
    breakcircle();
    printf("%lld\n",ans);
    return 0;
}

T2 "CQOI2016" routing table

topic

click here

Examination room thinking

Series title is too long skip
This question is ... is it the last generation to see that the length of the paper it ... skip

Correct

After finished, read over the resistant heart problem and found that this question is actually can do.
First, get to know the meaning of the questions, the mask is that it will use the length, while the other did not use the place, direct throw on it ...
Operation \ (A \) :
Enter a URL, the URL is added into the sequence of
operation \ (Q \) :
ask a URL \ (Web \) , in \ (a \) to \ (b \) when adding URL URL sequence, \ (Web \) to send objects will change many times.
What is it to send objects?
Is able to match its , and the longest and most accurate URL
and then think about it, is not that \ (trie \) tree it?
Join URL, that is, \ (trie \) tree to add a length 网址掩码binary string.
But because the inquiry is at a different point in time, we have to build a persistent \ (trie \) tree.
But the operation \ (Q \) it?
Let's think about the occurrence send objects change phenomenon (Not a professional name, but the author's own nameWhen short hair change phenomena), in the end what happened below.
By definition, change is made to the query URL \ (Web \) match, the longest and adding precise URL \ (A \) to \ (B \) when the URL changes.
Why change?
Suppose we (i \) \ moment, add a URL \ (the X-\) , in \ (j \) time, add the URL \ (y \) , so \ (y \) to ask \ (web \) is better than \ (x \) is.
So, the discussion \ (i \) and \ (j \) relationship

  • When \ (i <j \) , we at the time \ (I \) to \ (J-. 1 \) , it must be a URL \ (X \) , and when the time \ (J \) to the time , hair change phenomenon occurs, send objects \ (x \) becomes \ (the y-\) .
  • When \ (i> j \) , the description \ (i \) there than before \ (x \) better website, then will not change phenomenon of hair

Therefore, only the required \ (i <j \) and \ (Y \) than \ (X \) the situation on the line.
So how to deal with it?
A good question, but we look at this form:
\ (i <J \) and \ (y \) is better than \ (x \)
naturally think of monotonous stackAlthough I found the teacher reminded
This how a monotonous law?
If we are in chronological order, add URLs to the URL of the merits of monotonous object, then the time complexity is \ (O (ba) \) level
Oh, \ (1e6 \) play a hammer :).
If the merits of our website to order, into time.
Then the complexity of it up to \ (O (32) \) (chain length)
let me talk about the details.
, Traversing this chain of nodes (from the root to the leaves, which is the default URL from the inferior to superior) , met to consider how to put a end of its time \ (t \) .
Assume stack \ (Top <t \) , very harmonious, are our own people.
But if \ (Top> t \) , harmony ass, all get out, then ... \ (POP \) to \ (top \) again less than \ (t \) only to find, oh, this is one of us Do not shoot ...
then ... is the code

#include<cstdio>
#include<stack>
using namespace std;
#define rep(q,a,b) for(int q=a,q##_end_=b;q<=q##_end_;++q)
#define dep(q,a,b) for(int q=a,q##_end_=b;q>=q##_end_;--q)
template<class T>inline void qread(T& x){
    char c;bool f=false;x=0;
    while((c=getchar())<'0'||'9'<c)if(c=='-')f=true;
    for(x=(c^48);'0'<=(c=getchar())&&c<='9';x=(x<<1)+(x<<3)+(c^48));
    if(f)x=-x;
}
template<class T,class... Args>inline void qread(T& x,Args&... args){qread(x),qread(args...);}
inline int rqread(){
    char c;bool f=false;int x=0;
    while((c=getchar())<'0'||'9'<c)if(c=='-')f=true;
    for(x=(c^48);'0'<=(c=getchar())&&c<='9';x=(x<<1)+(x<<3)+(c^48));
    return f?-x:x;
}
template<class T>inline T Max(const T x,const T y){return x>y?x:y;}
template<class T>inline T Min(const T x,const T y){return x<y?x:y;}
template<class T>inline T fab(const T x){return x>0?x:-x;}
inline void getInv(int inv[],const int r,const int MOD)
{inv[0]=inv[1]=1;for(int i=2;i<=r;++i)inv[i]=1ll*inv[MOD%i]*(MOD-MOD/i)%MOD;}

const int MAXM=1e6;

struct node{
    int son[2],siz,ed;
}tre[MAXM*32+5];
int rt[MAXM+5],Ncnt,cnt;

inline void add(const unsigned int v,const int len,const int t){
    rt[++cnt]=++Ncnt;
    int newnode=rt[cnt],pre=rt[cnt-1];
    tre[newnode]=tre[pre];
    for(int i=31,now;i>=31-len+1;--i){
        now=(v>>i)&1;//取出从高到低第 i 位
        pre=tre[pre].son[now];
        tre[newnode].son[now]=++Ncnt;
        newnode=tre[newnode].son[now];//同步向下

        tre[newnode]=tre[pre];//继承上一个点信息
        ++tre[newnode].siz;
    }
    if(!tre[newnode].ed)tre[newnode].ed=t;
}

inline int getMaxl(int p,const unsigned int v){
    p=rt[p];
    int ret=0;
    for(int i=31,now;i>=0;--i){
        //这句话不能放到这里
        // if(tre[p].ed)ret=Max(ret,31-i+1);
        now=(v>>i)&1;
        if(tre[p].son[now])p=tre[p].son[now];
        else break;
        if(tre[p].ed)ret=Max(ret,31-i+1);
        //放到开头不行
    }
    return ret;
}

inline int query(int l,int r,const unsigned int v,const int len){
    l=rt[l],r=rt[r];
    stack<int>sta;
    for(int i=31,now;i>=0;--i){
        now=(v>>i)&1;
        if(tre[tre[r].son[now]].siz-tre[tre[l].son[now]].siz)//有地方可走
            r=tre[r].son[now],l=tre[l].son[now];
        else break;
        if(tre[r].ed&&31-i+1>len){//第二个条件的意思:这个点是否是掩码之内
            while(!sta.empty()&&tre[r].ed<sta.top())sta.pop();
            sta.push(tre[r].ed);
        }
    }
    return (int)sta.size();
}

char ord;
int M,len,l,r;
unsigned int a[4];

signed main(){
    qread(M);
    for(int t=1;t<=M;++t){
        scanf("%s",&ord);
        if(ord=='A'){
            scanf("%d.%d.%d.%d/%d",&a[0],&a[1],&a[2],&a[3],&len);
            for(int i=1;i<=3;++i)a[0]=a[0]<<8|a[i];
            add(a[0],len,t);
        }
        else{
            scanf("%d.%d.%d.%d %d %d",&a[0],&a[1],&a[2],&a[3],&l,&r);
            for(int i=1;i<=3;++i)a[0]=a[0]<<8|a[i];
            len=getMaxl(l-1,a[0]);
            printf("%d\n",query(l-1,r,a[0],len));
        }
    }
    return 0;
}

Ideas sourcesGangster's blog


T3 "NOIP2014" flying bird

topic

click here

Examination room thinking

When the exam and found this question is actually very water, and then began to cheat points ...
define \ (dp [i] [J] \) : come to the point \ ((i, j) \ ) minimum cost when.
Initialized memset(dp,127,sizeof dp)
special treatment \ (dp [i] [j ] = - 1 \) is a column can not go.
Then the first \ (0 \) discharge initial attach \ (0 \) .
The last sentence of the last row is not all as 2139062143you can.
Estimated fractional \ (100 pts \) , the actual score \ (40pts \) .
Do not ask me why, understand the meaning of the questions wrong ...

#include<cstdio>
#include<cstring>
#define rep(q,a,b) for(int q=a,q##_end_=b;q<=q##_end_;++q)
#define dep(q,a,b) for(int q=a,q##_end_=b;q>=q##_end_;--q)
template<class T>inline void qread(T& x){
    char c;bool f=false;x=0;
    while((c=getchar())<'0'||'9'<c)if(c=='-')f=true;
    for(x=(c^48);'0'<=(c=getchar())&&c<='9';x=(x<<1)+(x<<3)+(c^48));
    if(f)x=-x;
}
template<class T,class... Args>inline void qread(T& x,Args&... args){qread(x),qread(args...);}
inline int rqread(){
    char c;bool f=false;int x=0;
    while((c=getchar())<'0'||'9'<c)if(c=='-')f=true;
    for(x=(c^48);'0'<=(c=getchar())&&c<='9';x=(x<<1)+(x<<3)+(c^48));
    return f?-x:x;
}
template<class T>inline T Max(const T x,const T y){return x>y?x:y;}
template<class T>inline T Min(const T x,const T y){return x<y?x:y;}
template<class T>inline T fab(const T x){return x>0?x:-x;}
inline void getInv(int inv[],const int r,const int MOD)
{inv[0]=inv[1]=1;for(int i=2;i<=r;++i)inv[i]=1ll*inv[MOD%i]*(MOD-MOD/i)%MOD;}

const int MAXN=1e4;
const int MAXM=1e3;

int N,M,K,x[MAXN+5],y[MAXN+5];
int dp[MAXN+5][MAXM+5];
bool flg[MAXN+5];
int pre[MAXN+5],lst;

inline void special(){
    puts("0");
    for(int i=1;i<=N;++i){
        pre[i]=pre[i-1]+flg[i-1];
    }
    printf("%d\n",pre[lst]);
}

signed main(){
    qread(N,M,K);
    for(int i=0;i<N;++i)qread(x[i],y[i]);
    memset(dp,127,sizeof dp);
    for(int i=1,p,l,h;i<=K;++i){qread(p,l,h);
        flg[p]=true;
        for(int j=0;j<l;++j)dp[p][j]=-1;//理解错误部分
        for(int j=h+1;j<=M;++j)dp[p][j]=-1;//理解错误部分
    }
    for(int j=0;j<=M;++j)if(dp[0][j]!=-1)dp[0][j]=0;
    for(int i=0;i<N;++i)for(int j=0;j<=M;++j)if(dp[i][j]!=-1){
        if(i!=1&&j==0)continue;
        if(j-y[i]>=1){
            if(dp[i+1][j-y[i]]!=-1)dp[i+1][j-y[i]]=Min(dp[i+1][j-y[i]],dp[i][j]);
        }
        if(j+x[i]>M){
            if(dp[i+1][M]!=-1)dp[i+1][M]=Min(dp[i+1][M],dp[i][j]+1);
            if(dp[i][M]!=-1)dp[i][M]=Min(dp[i][M],dp[i][j]+1);//理解错误部分
        }
        else{
            if(dp[i+1][j+x[i]]!=-1)dp[i+1][j+x[i]]=Min(dp[i+1][j+x[i]],dp[i][j]+1);
            if(dp[i][j+x[i]]!=-1)dp[i][j+x[i]]=Min(dp[i][j+x[i]],dp[i][j]+1);//理解错误部分
        }
        if(dp[i][j]!=2139062143)lst=i;
    }
    int ans=2139062143;
    for(int i=1;i<=M;++i)ans=Min(ans,dp[N][i]);
    if(ans==2139062143)special();
    else printf("1\n%d\n",ans);
    return 0;
}

Correct

In fact, the title vulnerability by said pipeline is \ ((l, h) \ ) instead of \ ([l, h] \ )
Then I almost overturned
But after the change is \ (75pts \) , the title was later discovered there is a point of reading the wrong ...
This is not good at the language of Section weak
It was discovered that when the bird continuous jump, the jump height of the previous one \ (the X-\) .
I goThis question is really the intentions of the sample, making their feet ... data
specific ideas well thought completely backpack rising, while falling \ (01 \) backpack, then you can deal with some of the details.
Part of the code:
Consider a backpack full practice of the risingHere I'm too lazy, too lazy to special judge, to play more of a loop to process

for(int j=x[i-1]+1;j<=x[i-1]+M;++j)
    dp[i][j]=Min(dp[i][j-x[i-1]]+1/*上一列连续按*/,dp[i-1][j-x[i-1]]+1/*只按了一下*/);
for(int j=M+1;j<=M+x[i-1];++j)
    dp[i][M]=Min(dp[i][M],dp[i][j]);//最后把跳出去的部分全部归到 dp[i][M] 中

Decline when transferring directly from one up to

for(int j=1;j<=M-y[i-1];++j)
    dp[i][j]=Min(dp[i][j],dp[i-1][j+y[i-1]]);//注意此处没有 +1

The last part of the column about special treatment

for(int j=1;j<l[i];++j)dp[i][j]=INF;
for(int j=h[i]+1;j<=M;++j)dp[i][j]=INF;

Here the code is complete, the time complexity \ (O (the NM) \) , the spatial complexity \ (N (N + M) \) , but in fact may be optimized to \ (M \) .

#include<cstdio>
#include<cstring>
#define rep(q,a,b) for(int q=a,q##_end_=b;q<=q##_end_;++q)
#define dep(q,a,b) for(int q=a,q##_end_=b;q>=q##_end_;--q)
template<class T>inline void qread(T& x){
    char c;bool f=false;x=0;
    while((c=getchar())<'0'||'9'<c)if(c=='-')f=true;
    for(x=(c^48);'0'<=(c=getchar())&&c<='9';x=(x<<1)+(x<<3)+(c^48));
    if(f)x=-x;
}
template<class T,class... Args>inline void qread(T& x,Args&... args){qread(x),qread(args...);}
inline int rqread(){
    char c;bool f=false;int x=0;
    while((c=getchar())<'0'||'9'<c)if(c=='-')f=true;
    for(x=(c^48);'0'<=(c=getchar())&&c<='9';x=(x<<1)+(x<<3)+(c^48));
    return f?-x:x;
}
template<class T>inline T Max(const T x,const T y){return x>y?x:y;}
template<class T>inline T Min(const T x,const T y){return x<y?x:y;}
template<class T>inline T fab(const T x){return x>0?x:-x;}
inline void getInv(int inv[],const int r,const int MOD)
{inv[0]=inv[1]=1;for(int i=2;i<=r;++i)inv[i]=1ll*inv[MOD%i]*(MOD-MOD/i)%MOD;}

const int MAXN=1e4;
const int MAXM=1e3;
const int INF=66666666;//十分吉祥

int dp[MAXN+5][(MAXM<<1)+5];
int l[MAXN+5],h[MAXN+5];
int x[MAXN+5],y[MAXN+5];
int N,M,K,ans2;bool flg[MAXN+5],lst;

signed main(){
    qread(N,M,K);
    for(int i=0;i<N;++i)qread(x[i],y[i]),l[i]=1,h[i]=M;
    l[N]=1,h[N]=M;
    for(int i=1,p,a,b;i<=K;++i){qread(p,a,b);
        flg[p]=true;
        l[p]=a+1;
        h[p]=b-1;
    }
    memset(dp,0x3f,sizeof dp);
    for(int j=0;j<=M;++j)dp[0][j]=0;
    for(int i=1;i<=N;++i){
        lst=false;
        for(int j=x[i-1]+1;j<=x[i-1]+M;++j)
            dp[i][j]=Min(dp[i][j-x[i-1]]+1,dp[i-1][j-x[i-1]]+1);
        for(int j=M+1;j<=M+x[i-1];++j)
            dp[i][M]=Min(dp[i][M],dp[i][j]);
        for(int j=1;j<=M-y[i-1];++j)
            dp[i][j]=Min(dp[i][j],dp[i-1][j+y[i-1]]);
        for(int j=1;j<l[i];++j)dp[i][j]=INF;
        for(int j=l[i];j<=h[i];++j)if(dp[i][j]<INF){lst=true;break;}//计算这一列可不可以到
        for(int j=h[i]+1;j<=M;++j)dp[i][j]=INF;
        if(lst&&flg[i])++ans2;//处理一下第二个答案
    }
    int ans=INF;
    for(int j=1;j<=M;++j)ans=Min(ans,dp[N][j]);
    if(ans<INF)return 0&printf("1\n%d\n",ans);
    else printf("0\n%d\n",ans2);
    return 0;
}

Is overturned day

Guess you like

Origin www.cnblogs.com/Arextre/p/12210493.html