noip模拟71[水]

noip模拟71 solutions

所以这套题是真的水,我差点就300分了!!!

T1 签到题

这个题我也不会证,就直接看度数是否可以整除这个颜色数

好像原因是二分图可以瞎搞

AC_code
#include<bits/stdc++.h>
using namespace std;
#define oj
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
const int N=1e6+5;
int n,m,k,c,ans;
int dn[N],dm[N];
signed main(){
    #ifdef oj
        freopen("qiandao.in","r",stdin);
        freopen("qiandao.out","w",stdout);
    #endif
    scanf("%d%d%d%d",&n,&m,&k,&c);
    fo(i,1,k){
        int x,y;scanf("%d%d",&x,&y);
        dn[x]++;dm[y]++;
    }
    fo(i,1,n)if(dn[i]%c)ans++;
    fo(i,1,m)if(dm[i]%c)ans++;
    printf("%d",ans);
}   

T2 M弟娃

树剖+线段树+倍增

大板子

AC_code
#include<bits/stdc++.h>
using namespace std;
#define oj
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
const int N=3e5+5;
int n,m;
int to[N*2],nxt[N*2],head[N],rp;
void add_edg(int x,int y){
    to[++rp]=y;
    nxt[rp]=head[x];
    head[x]=rp;
}
int siz[N],son[N],dep[N],fa[N],top[N];
int dfn[N],dfm[N],cnt;
int st[N][21];
void dfs_fi(int x,int f){
    siz[x]=1;son[x]=0;
    for(int i=head[x];i;i=nxt[i]){
        int y=to[i];
        if(y==f)continue;
        dep[y]=dep[x]+1;fa[y]=x;
        dfs_fi(y,x);
        siz[x]+=siz[y];
        if(!son[x]||siz[y]>siz[son[x]])son[x]=y;
    }
}
void dfs_se(int x,int f){
    top[x]=f;dfn[x]=++cnt;
    st[x][0]=fa[x];
    fo(i,1,20)st[x][i]=st[st[x][i-1]][i-1];
    if(son[x])dfs_se(son[x],f);
    for(int i=head[x];i;i=nxt[i]){
        int y=to[i];
        if(y==fa[x]||y==son[x])continue;
        dfs_se(y,y);
    }
    dfm[x]=cnt;
}
int LCA(int x,int y){
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]])swap(x,y);
        x=fa[top[x]];
    }
    return dep[x]<dep[y]?x:y;
}
struct XDS{
    #define ls x<<1
    #define rs x<<1|1
    int mx[N*5],tg[N*5];
    void pushup(int x){
        mx[x]=max(mx[ls],mx[rs]);
        return ;
    }
    void pushdown(int x){
        if(!tg[x])return ;
        tg[ls]+=tg[x];
        mx[ls]+=tg[x];
        tg[rs]+=tg[x];
        mx[rs]+=tg[x];
        tg[x]=0;
        return ;
    }
    void ins(int x,int l,int r,int ql,int qr){
        if(ql>qr)return ;
        if(ql<=l&&r<=qr){
            tg[x]++;mx[x]++;
            return ;
        }
        pushdown(x);
        int mid=l+r>>1;
        if(ql<=mid)ins(ls,l,mid,ql,qr);
        if(qr>mid)ins(rs,mid+1,r,ql,qr);
        pushup(x);return ;
    }
    #undef ls
    #undef rs
}xds;
signed main(){
    #ifdef oj
        freopen("magic.in","r",stdin);
        freopen("magic.out","w",stdout);
    #endif
    scanf("%d%d",&n,&m);
    fo(i,1,n-1){
        int x,y;scanf("%d%d",&x,&y);
        add_edg(x,y);add_edg(y,x);
    }
    dep[1]=1;dfs_fi(1,0);dfs_se(1,1);
    fo(i,1,m){
        int x,y;scanf("%d%d",&x,&y);
        int lca=LCA(x,y);
        if(x==y)xds.ins(1,1,n,1,n);
        else if(lca==x){
            int now=y;
            fu(j,20,0)if(dep[st[now][j]]>dep[lca])now=st[now][j];
            //cout<<"zz"<<x<<" "<<y<<" "<<now<<" "<<lca<<" ";
            //if(fa[now]==x||x==y)cout<<"sb";
            xds.ins(1,1,n,1,dfn[now]-1);
            xds.ins(1,1,n,dfm[now]+1,n);
            //xds.ins(1,1,n,dfn[x],dfn[x]);
            xds.ins(1,1,n,dfn[y],dfm[y]);
        }
        else if(lca==y){
            int now=x;
            fu(j,20,0)if(dep[st[now][j]]>dep[lca])now=st[now][j];
            //cout<<"zz"<<x<<" "<<y<<" "<<now<<" "<<lca<<" ";
            //if(fa[now]==y||x==y)cout<<"sb";
            xds.ins(1,1,n,1,dfn[now]-1);
            xds.ins(1,1,n,dfm[now]+1,n);
            //xds.ins(1,1,n,dfn[y],dfn[y]);
            xds.ins(1,1,n,dfn[x],dfm[x]);
        }
        else {
            xds.ins(1,1,n,dfn[x],dfm[x]);
            xds.ins(1,1,n,dfn[y],dfm[y]);
        }
        printf("%d\n",xds.mx[1]);
    }
}

T3 变异大老鼠

就是一个树上的背包,我考场上竟然没有看出来

主要是我树都建好了

AC_code
#include<bits/stdc++.h>
using namespace std;
#define oj
#define int long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
const int N=305;
const int M=N*N;
const int inf=0x3f3f3f3f3f3f3f3f;
int n,m,k;
int edg[N][N],dis[N],who[N];
bool vis[N];
int to[N],nxt[N],head[N],rp;
void add_edg(int x,int y){
    to[++rp]=y;
    nxt[rp]=head[x];
    head[x]=rp;
}
void redg(){
    memset(dis,0x3f,sizeof(dis));
    dis[1]=0;vis[1]=true;
    fo(i,1,n)if(!vis[i]&&dis[i]>edg[1][i])dis[i]=edg[1][i],who[i]=1;
    fo(j,2,n){
        int mn=inf,wo;
        fo(i,1,n){
            if(vis[i])continue;
            if(dis[i]<mn)mn=dis[i],wo=i;
        }
        vis[wo]=true;add_edg(who[wo],wo);
        //cout<<who[wo]<<" "<<wo<<endl;
        fo(i,1,n){
            if(vis[i])continue;
            if(dis[i]>dis[wo]+edg[wo][i])
                dis[i]=dis[wo]+edg[wo][i],who[i]=wo;
        }
    }
}
double gl[N][N],ans;
double f[N][N],g[N][N];
void dfs(int x){
    if(!head[x]){
        fo(i,0,k)f[x][i]=gl[x][i];
        return ;
    }
    int tot=0;
    for(int i=head[x];i;i=nxt[i]){
        int y=to[i];
        dfs(y);
        fu(o,k,0){
            fo(j,0,o)
                g[x][o]=max(g[x][o],g[x][o-j]+f[y][j]);
        }
        tot++;
    }
    fo(i,0,k)g[x][i]/=tot;
    fo(i,0,k){
        fo(j,i,k){
            f[x][j]=max(f[x][j],gl[x][i]+(1.0-gl[x][i])*g[x][j-i]);
        }
    }
    // cout<<x<<" ";
    // fo(i,0,k)cout<<f[x][i]<<" ";cout<<endl;
}
signed main(){
    #ifdef oj
        freopen("arrest.in","r",stdin);
        freopen("arrest.out","w",stdout);
    #endif
    scanf("%lld%lld%lld",&n,&m,&k);
    memset(edg,0x3f,sizeof(edg));
    fo(i,1,m){
        int x,y,z;scanf("%lld%lld%lld",&x,&y,&z);
        edg[x][y]=edg[y][x]=min(edg[y][x],z);
    }
    fo(i,1,n)fo(j,1,k)scanf("%lf",&gl[i][j]);
    redg();dfs(1);ans=f[1][k];
    printf("%.6lf",ans);
}

T4 朝鲜时蔬

就是测试点分治,直接推式子就好了

AC_code
#include<bits/stdc++.h>
using namespace std;
#define oj
#define int long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
const int mod=1e9+7;
int n,m,k,ans;
int ksm(int x,int y){
    int ret=1;
    while(y){
        if(y&1)ret=ret*x%mod;
        x=x*x%mod;y>>=1;
    }return ret;
}
int jc[10];
signed main(){
    #ifdef oj
        freopen("vegetable.in","r",stdin);
        freopen("vegetable.out","w",stdout);
    #endif
    scanf("%lld%lld%lld",&n,&m,&k);
    jc[0]=1;fo(i,1,m)jc[i]=jc[i-1]*i%mod;
    if(m==k){
        n%=mod;ans=1;
        fo(i,0,m-1)ans=ans*(n-i)%mod;
        ans=ans*ksm(jc[m],mod-2)%mod;
    }
    if(m==2&&k==1){
        int l=1,r;
        while(l<=n){
            r=n/(n/l);
            ans=(ans+(r-l+1)%mod*(n/l-1)%mod)%mod;
            l=r+1;
        }
    }
    if(m==3&&k==1){
        ans=(n/3)%mod;
    }
    if(m==3&&k==2){
        int l=1,r;
        while(l<=n){
            r=n/(n/l);
            int a=l-1>>1,b=r-1>>1;
            int res=(a+b)%mod*((b-a+1)%mod)%mod;
            if((l^1)&1)res=(res-a%mod+mod)%mod;
            if(r&1)res=(res-b%mod+mod)%mod;
            ans=(ans+res%mod*((n/l)%mod)%mod)%mod;
            l=r+1;
        }
    }
    if(m==4&&k==1){
        if(n==4||n==5)ans=1;
        else ans=((n/6)%mod+(n/9)%mod+(n/10)%mod+(n/12)%mod+(n/15)%mod+(n/21)%mod)%mod;
    }
    if(m==4&&k==2){
        switch(n){
            case 4:ans=1;break;
            case 5:ans=1;break;
            case 6:ans=1;break;
            case 7:ans=3;break;
            case 8:ans=6;break;
            case 9:ans=9;break;
            case 10:ans=10;break;
        }
        if(n>10)ans=((n/11)%mod+(n/29)%mod)%mod;
    }
    if(m==4&&k==3){
        if(n==4)ans=1;
        else if(n==5)ans=5;
        else {
            int l=1,r;
            while(l<=n){
                r=n/(n/l);
                int a=l-1>>1,b=r-1>>1;
                int res=(a+b)%mod*((b-a+1)%mod)%mod;
                if((l^1)&1)res=(res-a%mod+mod)%mod;
                if(r&1)res=(res-b%mod+mod)%mod;
                res=(mod-res*3%mod)%mod;
                res=(res+((r/3)-((l-1)/3))*2%mod)%mod;
                res=(res+r%mod*((r-1)%mod)%mod*((r-2)%mod)%mod*ksm(jc[3],mod-2)%mod)%mod;
                res=(res+mod-(l-1)%mod*((l-2)%mod)%mod*((l-3)%mod)%mod*ksm(jc[3],mod-2)%mod)%mod;
                res=res*ksm(6,mod-2)%mod;
                ans=(ans+res%mod*((n/l)%mod)%mod)%mod;
                l=r+1;
            }
        }
    }
    printf("%lld",ans);
}
posted @ 2021-10-07 21:16  fengwu2005  阅读(40)  评论(0编辑  收藏  举报