zoukankan      html  css  js  c++  java
  • 【NOIP2016】补题

    今天突然想到自己居然还没把NOIP2016补完

    简直是傻逼、、、

    所以开始写

    D1T1:模拟

    D1T2:NOIP最难的一道题,首先求LCA

    离线下,把观察员单独提出来

    然后可以维护一个类似桶排序的东西

    #include<bits/stdc++.h>
    #define N 400010
    using namespace std;
    int n,m,top[N],wson[N],size[N],tot=0,head[N],w[N],fa[N],d[N];
    struct Edge{int u,v,next;}G[N<<1],E[N<<1];
    int f[N<<1],g[N<<1],ans[N],ind[N][2],out[N][2];
    inline void addedge(int u,int v){
        G[++tot].u=u;G[tot].v=v;G[tot].next=head[u];head[u]=tot;
        G[++tot].u=v;G[tot].v=u;G[tot].next=head[v];head[v]=tot;
    }
    int head1[N],tot2=0;
    inline void addedge2(int &u,int v){
        E[++tot2].u=u;E[tot2].v=v;E[tot2].next=u;u=tot2;
    }
    inline void addquery(int t,int x,int y,int lca){
        addedge2(ind[x][t],lca);
        if(y>1)addedge2(out[fa[y]][t],lca);
    }
    inline int read(){
        int f=1,x=0;char ch;
        do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
        do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
        return f*x;
    }
    void dfs1(int u,int f){
        size[u]=1;
        for(int i=head[u];i;i=G[i].next){
            int v=G[i].v;if(v==f)continue;
            fa[v]=u;d[v]=d[u]+1;
            dfs1(v,u);
            size[u]+=size[v];
            if(size[v]>size[wson[u]])wson[u]=v;
        }
    }
    void dfs2(int u,int tp){
        top[u]=tp;if(wson[u])dfs2(wson[u],tp);
        for(int i=head[u];i;i=G[i].next){
            int v=G[i].v;if(v==fa[u]||v==wson[u])continue;
            dfs2(v,v);
        }
    }
    inline int qlca(int x,int y){
        while (top[x]!=top[y]){
            if(d[top[x]]<d[top[y]])swap(x,y);
            x=fa[top[x]];
        }
        if(d[x]>d[y])swap(x,y);return x;
    }
    void dfs3(int u){
        ans[u]-=f[w[u]+d[u]]+g[w[u]-d[u]+N];
        for(int i=ind[u][0];i;i=E[i].next)f[E[i].v]++;
        for(int i=out[u][0];i;i=E[i].next)f[E[i].v]--;
        for(int i=ind[u][1];i;i=E[i].next)g[E[i].v+N]++;
        for(int i=out[u][1];i;i=E[i].next)g[E[i].v+N]--;
        for(int i=head[u];i;i=G[i].next)if(G[i].v!=fa[u])dfs3(G[i].v);
        ans[u]+=f[w[u]+d[u]]+g[w[u]-d[u]+N];
    }
    int main(){
        n=read();m=read();
        for(int i=1;i<n;i++){addedge(read(),read());}
        for(int i=1;i<=n;i++)w[i]=read();
        dfs1(1,0);dfs2(1,1);
        for(int i=1;i<=m;i++){
            int x=read(),y=read(),lca=qlca(x,y);
            if(d[x]-d[lca]==w[lca])ans[lca]--;
            addquery(0,x,lca,d[x]);addquery(1,y,lca,d[x]-2*d[lca]);
        }
        dfs3(1);
        for(int i=1;i<=n;i++)printf("%d ",ans[i]);puts("");
    }

    D1T3:其实是很简单的概率dp,但是转移的时候讨论比较恶心。

    #include<bits/stdc++.h>
    #define inf 1000000007
    using namespace std;
    int n,m,v,e,c[2010],d[2010];double dis[305][305];
    double p[2010],dp[2010][2010][2];
    inline void floyed(){
        for(int k=1;k<=v;k++)
        for(int i=1;i<=v;i++)
        for(int j=1;j<=v;j++)dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
    }
    inline int read(){
        int f=1,x=0;char ch;
        do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
        do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
        return f*x;
    }
    int main(){
        n=read();m=read();v=read();e=read();
        for(int i=1;i<=n;i++)c[i]=read();for(int i=1;i<=n;i++)d[i]=read();
        for(int i=1;i<=n;i++)scanf("%lf",&p[i]);
        for(int i=1;i<=v;i++)for(int j=1;j<=v;j++)if(i==j)dis[i][j]=0;else dis[i][j]=inf;
        for(int i=1;i<=e;i++){
            int u,v;double w;scanf("%d%d%lf",&u,&v,&w);
            dis[u][v]=dis[v][u]=min(dis[u][v],w);
        }
        floyed();
    for(int i=1;i<=n;i++)for(int j=0;j<=m;j++)dp[i][j][0]=dp[i][j][1]=inf;
        dp[1][0][0]=0;dp[1][1][1]=0;
        for(int i=2;i<=n;i++)
            for(int j=0;j<=m;j++){
                dp[i][j][0]=min(dp[i-1][j][0]+dis[c[i]][c[i-1]],dp[i-1][j][1]+dis[c[i]][c[i-1]]*(1-p[i-1])+dis[c[i]][d[i-1]]*p[i-1]);
                if(j>0){
                    double tmp1=0,tmp2=0;
                    tmp1=(dp[i-1][j-1][0]+dis[d[i]][c[i-1]])*p[i]+(dp[i-1][j-1][0]+dis[c[i]][c[i-1]])*(1-p[i]);
                    tmp2=(dp[i-1][j-1][1]+dis[d[i]][d[i-1]]*p[i-1]+dis[d[i]][c[i-1]]*(1-p[i-1]))*p[i]+(dp[i-1][j-1][1]+dis[c[i]][d[i-1]]*p[i-1]+dis[c[i]][c[i-1]]*(1-p[i-1]))*(1-p[i]);
                    dp[i][j][1]=min(tmp1,tmp2);
                }
        }
        double ans=inf;for(int i=0;i<=m;i++)ans=min(ans,min(dp[n][i][0],dp[n][i][1]));
        printf("%.2lf
    ",ans);
    }

    D2T1:参见之前blog

    D2T2:比较妙的一道题,证明完之后三个单调队列即可。

    #include<bits/stdc++.h>
    #define N 7100007
    #define inf 0x7fffffff
    using namespace std;
    typedef long long ll;
    int n,m,q,u,v,tot;
    ll k,t,ans,x,y,delt;
    ll Q[3][N],l[3],r[3];
    bool cmp(int x,int y){return x>y;}
    inline int read(){
        int f=1,x=0;char ch;
        do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
        do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
        return f*x;
    }
    int main(){
        n=read();m=read();q=read();u=read();v=read();tot=read();
        for(int i=1;i<=m+n;i++)Q[0][i]=Q[1][i]=Q[2][i]=-inf;
        for(int i=1;i<=n;i++)scanf("%lld",&Q[0][i]);
        sort(Q[0]+1,Q[0]+n+1,cmp);
        l[0]=1,r[0]=n;l[1]=l[2]=1;r[1]=r[2]=0;
        for(int i=1;i<=m;i++){
            delt=-inf;for(int j=0;j<=2;j++)if(Q[j][l[j]]>delt)delt=Q[j][l[j]],k=j;
            ll t=delt+(i-1)*q;l[k]++;
            if(i%tot==0)printf("%lld ",t);
            x=t*u/v;y=t-x;
            Q[1][++r[1]]=x-i*q;
            Q[2][++r[2]]=y-i*q;
        }
        puts("");
        for(int i=1;i<=m+n;i++){
            delt=-inf;for(int j=0;j<=2;j++)if(Q[j][l[j]]>delt)delt=Q[j][l[j]],k=j;
            t=delt+m*q;l[k]++;
            if(i%tot==0)printf("%lld ",t);
        }
    }

    D2T3:状压dp,参考之前blog。

  • 相关阅读:
    不可或缺 Windows Native (15)
    不可或缺 Windows Native (14)
    不可或缺 Windows Native (13)
    不可或缺 Windows Native (12)
    不可或缺 Windows Native (11)
    不可或缺 Windows Native (10)
    不可或缺 Windows Native (9)
    不可或缺 Windows Native (8)
    不可或缺 Windows Native (7)
    不可或缺 Windows Native (6)
  • 原文地址:https://www.cnblogs.com/zcysky/p/7171854.html
Copyright © 2011-2022 走看看