2 条题解

  • 0
    @ 2017-11-07 20:00:18

    #pra\
    gma GCC optimize("O3")
    #include <iostream>
    #include <iomanip>
    #include <cstdio>
    #include <cstdlib>

    #include <cstring>
    #include <cmath>
    #include <string>
    #include <cctype>

    #include <algorithm>
    #include <queue>
    #include <stack>

    using namespace std;
    int N,Q;
    int BB[200010],LL[200010];

    struct edge{
    int ed,next;
    }E[1000100];
    int head[200010],Ecnt;
    //type
    struct mx2{int vv[2];};
    struct mx4{int vv[4];}MINUS_INF{-0x3f3f3f3f,-0x3f3f3f3f,-0x3f3f3f3f,-0x3f3f3f3f};
    //seg_tree
    int fa[200010],size[200010];
    int sid[200010],scnt,real[200010];
    mx4 T[2000100];
    //dp
    mx4 f[200010];
    // code
    inline void addEdge(int st,int ed)
    {
    E[++Ecnt].ed=ed;
    E[Ecnt].next=head[st];
    head[st]=Ecnt;
    }
    inline mx4 merge_mx4(mx4 x,mx4 y)
    {
    mx4 ret=MINUS_INF;
    int pa=0,pr=0;
    static int a[8];
    memcpy(a,&x,sizeof x),memcpy(a+4,&y,sizeof y);
    sort(a,a+8,greater<int>());
    //int t=unique(a,a+6)-a-1;
    //memcpy(&ret,a,min(sizeof ret,sizeof(int)*(t+1)));
    while(pr<4&&pa<8)
    {
    if(pa==0||a[pa]!=a[pa-1]||(pa==1&&a[pa]==a[pa-1]))
    ret.vv[pr++]=a[pa];
    pa++;
    }

    return ret;
    }
    void dfs(int st)
    {
    //cout<<"dfs in"<<st<<endl;
    size[st]=1;
    sid[st]=++scnt;
    real[scnt]=st;
    f[st].vv[0]=BB[st];
    for(int i=head[st];i;i=E[i].next)
    {
    int ed=E[i].ed;
    if(ed!=fa[st])
    {
    fa[ed]=st;
    dfs(ed);
    size[st]+=size[ed];
    f[st]=merge_mx4(f[st],f[ed]);
    }
    }
    //printf("size %d=%d pair[%d,%d]\n",st,size[st],f[st].vv[0],f[st].vv[1]);
    }
    //seg_tree
    void build_tree(int L,int R,int id)
    {
    if(L==R)
    T[id].vv[0]=LL[real[L]];
    else
    {
    int mid=(L+R)>>1;
    build_tree(L,mid,id<<1);
    build_tree(mid+1,R,id<<1|1);
    T[id]=merge_mx4(T[id<<1|1],T[id<<1]);
    //T[id]=merge_mx4(T[id],T[id<<1|1]);
    }
    }
    mx4 query(int B,int E,int L,int R,int id)
    {
    if(L>E||R<B||E<B)
    return MINUS_INF;
    if(L>=B&&R<=E)
    return T[id];
    int mid=(L+R)>>1;
    return merge_mx4(query(B,E,L,mid,id<<1) , query(B,E,mid+1,R,id<<1|1));
    }
    //end of seg_tree
    void print_mx4(mx4 t)
    {
    printf("%d %d %d %d\n",t.vv[0],t.vv[1],t.vv[2],t.vv[3]);
    }
    void solve(mx4 mb,mx4 ml)
    {
    int ret=0;
    for(int i=1;i<=3;++i)
    for(int j=0;j<=3;++j)
    {
    int tmp=max(mb.vv[i],mb.vv[i]+ml.vv[j]);
    if(tmp!=mb.vv[0])
    tmp=min(tmp,mb.vv[0]);
    else
    tmp=0;
    ret=max(ret,tmp);
    }
    printf("%d\n",max(ret,0));
    }
    int main()
    {
    //freopen("C:\Users\Administrator\Downloads\1\Input\soldier14.in","r+",stdin);
    //freopen("1.txt","w+",stdout);
    scanf("%d%d",&N,&Q);
    for(int i=2;i<=N;++i)
    {
    int x;
    scanf("%d",&x);
    addEdge(i,x);
    addEdge(x,i);
    }
    for(int i=1;i<=N;++i)
    scanf("%d%d",BB+i,LL+i);
    memset(f,0xc0,sizeof f);
    memset(T,0xc0,sizeof T);
    dfs(1);
    build_tree(1,N,1);
    //printf("\t%d %d\n",LL[real[1]],real[1]);
    //print_mx4( query(1,1,1,N,1) );
    for(int i=1;i<=Q;++i)
    {
    int r;
    scanf("%d",&r);
    mx4 t1,t2;
    t1=f[r];
    t2=merge_mx4( query(sid[1],sid[r]-1,1,N,1) , query(sid[r]+size[r],N,1,N,1) );
    //print_mx4(query(sid[1],sid[r]-1,1,N,1)),print_mx4(query(sid[r]+size[r],N,1,N,1));
    //print_mx4(t1);
    //print_mx4(t2);
    solve(t1,t2);
    }
    return 0;
    }

  • 0
    @ 2017-11-06 21:43:04

    感谢dicboust提供题解。
    这个95分,大略就是维护第一大第二大第三大值之类的。因为很容易证明a%b<b所以尽量往上界加。但是注意不要a+c==b这样就前功尽弃啦。反正这个题解应该是写复杂了,主要就是处理这种特殊情况,必须搞个第三大值。最后5分实在是写不出来啦。
    #include <bits/stdc++.h>
    using namespace std;
    inline int read()
    {
    char ch=getchar();
    int x=0;
    while(!isdigit(ch))
    ch=getchar();
    while(isdigit(ch))
    {
    x=x*10+ch-'0';
    ch=getchar();
    }
    return x;
    }

    struct edge
    {
    int to,nex;
    }e[200010];
    int point[200010],cnt=0;
    inline void add(int x,int y)
    {
    e[++cnt].to=y;
    e[cnt].nex=point[x];
    point[x]=cnt;
    }

    struct node
    {
    int b,li;
    }a[200010];
    int n,q,s;
    int vis[200010];
    int dfn[200010],antidfn[200010],id=0,p[200010];
    void dfs(int x)
    {
    dfn[x]=++id,antidfn[id]=x;
    for(int i=point[x];i;i=e[i].nex)
    if(!dfn[e[i].to])
    dfs(e[i].to);
    p[x]=id;
    }

    struct tree
    {
    int l,r;
    int maxb1,maxb2,max_spe,maxb3;
    int maxli1,maxli2;
    }t[800010];

    void update_b(int i)
    {
    int tmp[8],j=6;
    tmp[0]=t[i<<1].maxb1;
    tmp[1]=t[i<<1].maxb2;
    tmp[2]=t[i<<1].maxb3;
    tmp[3]=t[i<<1].max_spe;
    tmp[4]=t[i<<1|1].maxb1;
    tmp[5]=t[i<<1|1].maxb2;
    tmp[6]=t[i<<1|1].maxb3;
    tmp[7]=t[i<<1|1].max_spe;
    sort(tmp,tmp+8);
    t[i].maxb1=tmp[7];
    while(tmp[j]==t[i].maxb1)
    j--;
    t[i].maxb2=tmp[j];
    if(j!=6)
    t[i].max_spe=tmp[7];
    else
    t[i].max_spe=0;
    while(tmp[j]==t[i].maxb2&&j>0)
    j--;
    t[i].maxb3=tmp[j];
    }
    void update_li(int i)
    {
    int tmp[4];
    tmp[0]=t[i<<1].maxli1;
    tmp[1]=t[i<<1].maxli2;
    tmp[2]=t[i<<1|1].maxli1;
    tmp[3]=t[i<<1|1].maxli2;
    sort(tmp,tmp+4);
    t[i].maxli1=tmp[3];
    if(tmp[2]!=tmp[3])
    t[i].maxli2=tmp[2];
    else
    t[i].maxli2=tmp[1];
    }

    void build(int x,int y,int i)
    {
    t[i].l=x,t[i].r=y;
    if(x==y)
    {
    t[i].maxb1=a[antidfn[x]].b;
    t[i].maxb2=t[i].maxb3=0;
    t[i].max_spe=0;
    t[i].maxli1=a[antidfn[x]].li;
    t[i].maxli2=0;
    }
    else
    {
    int mid=(x+y)>>1;
    build(x,mid,i<<1);
    build(mid+1,y,i<<1|1);
    update_b(i);
    update_li(i);
    }
    }

    struct query
    {
    int max1,max2,max3,max_spe;
    };
    query query_b(int x,int y,int i)
    {
    query tmp;
    if(x<=t[i].l&&t[i].r<=y)
    {
    tmp.max1=t[i].maxb1;
    tmp.max2=t[i].maxb2;
    tmp.max3=t[i].maxb3;
    tmp.max_spe=t[i].max_spe;
    return tmp;
    }
    int mid=(t[i].l+t[i].r)>>1;
    if(y<=mid)
    return query_b(x,y,i<<1);
    if(x>mid)
    return query_b(x,y,i<<1|1);
    query tmp1=query_b(x,y,i<<1);
    query tmp2=query_b(x,y,i<<1|1);
    int tmp_tmp[8],j=6;
    tmp_tmp[0]=tmp1.max1;
    tmp_tmp[1]=tmp1.max2;
    tmp_tmp[2]=tmp1.max3;
    tmp_tmp[3]=tmp1.max_spe;
    tmp_tmp[4]=tmp2.max1;
    tmp_tmp[5]=tmp2.max2;
    tmp_tmp[6]=tmp2.max3;
    tmp_tmp[7]=tmp2.max_spe;
    sort(tmp_tmp,tmp_tmp+8);
    tmp.max1=tmp_tmp[7];
    while(tmp_tmp[j]==tmp.max1)
    j--;
    tmp.max2=tmp_tmp[j];
    if(j!=6)
    tmp.max_spe=tmp_tmp[7];
    else
    tmp.max_spe=0;
    while(tmp_tmp[j]==tmp.max2&&j>0)
    j--;
    tmp.max3=tmp_tmp[j];
    return tmp;
    }

    query query_li(int x,int y,int i)
    {
    query tmp;
    if(x<=t[i].l&&t[i].r<=y)
    {
    tmp.max1=t[i].maxli1;
    tmp.max2=t[i].maxli2;
    return tmp;
    }
    int mid=(t[i].l+t[i].r)>>1;
    if(y<=mid)
    return query_li(x,y,i<<1);
    if(x>mid)
    return query_li(x,y,i<<1|1);
    query tmp1=query_li(x,y,i<<1);
    query tmp2=query_li(x,y,i<<1|1);
    int tmp_tmp[4];
    tmp_tmp[0]=tmp1.max1;
    tmp_tmp[1]=tmp1.max2;
    tmp_tmp[2]=tmp2.max1;
    tmp_tmp[3]=tmp2.max2;
    sort(tmp_tmp,tmp_tmp+4);
    tmp.max1=tmp_tmp[3];
    if(tmp_tmp[2]!=tmp_tmp[3])
    tmp.max2=tmp_tmp[2];
    else
    tmp.max2=tmp_tmp[1];
    return tmp;
    }
    int main()
    {
    //freopen("soldier1.in","r",stdin);
    //freopen("soldier.out","w",stdout);
    memset(point,0,sizeof(point));
    memset(vis,0,sizeof(vis));
    int i,x;
    n=read(),q=read();
    for(i=2;i<=n;i++)
    {
    x=read();
    vis[x]=1;
    add(x,i);
    }
    for(i=1;i<=n;i++)
    a[i].b=read(),a[i].li=read();
    memset(dfn,0,sizeof(dfn));
    dfs(1);
    build(1,n,1);
    //for(i=1;i<=n*2;i++)
    // printf("%d %d %d %d %d\n",t[i].l,t[i].r,t[i].maxb1,t[i].maxb2,t[i].max_spe);
    while(q--)
    {
    s=read();
    if(!vis[s])
    {
    cout<<0<<endl;
    continue;
    }
    query tmp_b=query_b(dfn[s],p[s],1);
    query tmp_li1,tmp_li2,tmp_li;
    if(dfn[s]!=1)
    {
    tmp_li1=query_li(1,dfn[s]-1,1);
    }
    else
    tmp_li1.max1=0,tmp_li1.max2=0;
    if(p[s]!=n)
    {
    tmp_li2=query_li(p[s]+1,n,1);
    }
    else
    tmp_li2.max1=0,tmp_li2.max2=0;
    int tmp_tmp[4];
    tmp_tmp[0]=tmp_li1.max1;
    tmp_tmp[1]=tmp_li1.max2;
    tmp_tmp[2]=tmp_li2.max1;
    tmp_tmp[3]=tmp_li2.max2;
    sort(tmp_tmp,tmp_tmp+4);
    tmp_li.max1=tmp_tmp[3];
    if(tmp_tmp[2]!=tmp_tmp[3])
    tmp_li.max2=tmp_tmp[2];
    else
    tmp_li.max2=tmp_tmp[1];
    //printf("%d %d %d %d %d\n",tmp_b.max1,tmp_b.max2,tmp_b.max_spe,tmp_li.max1,tmp_li.max2);
    if(tmp_li.max1==0)
    {
    cout<<tmp_b.max2<<endl;
    }
    else if(tmp_li.max2==0)
    {
    if(tmp_b.max1==tmp_b.max_spe)
    {
    cout<<tmp_b.max1<<endl;
    }
    else if(tmp_b.max2+tmp_li.max1==tmp_b.max1)
    {
    cout<<max(tmp_b.max2,tmp_b.max3+tmp_li.max1)<<endl;
    }
    else
    cout<<min(tmp_b.max1,tmp_b.max2+tmp_li.max1)<<endl;
    }
    else
    {
    if(tmp_b.max1==tmp_b.max_spe)
    {
    cout<<tmp_b.max1<<endl;
    }
    else if(tmp_b.max2+tmp_li.max1==tmp_b.max1)
    {
    cout<<max(tmp_b.max2+tmp_li.max2,tmp_b.max3+tmp_li.max1)<<endl;
    }
    else
    {
    cout<<min(tmp_b.max1,tmp_b.max2+tmp_li.max1)<<endl;
    }
    }
    }
    return 0;
    }

  • 1

士兵训练(CQ直辖市noip模拟赛) T3

信息

难度
10
分类
(无)
标签
(无)
递交数
69
已通过
0
通过率
0%
上传者