• 20191018


    前言

    • T3想到正解然而并没有时间打。
    • T1送分几乎都A了,T2概率我啥也不会。
    • 我会的别人都会+别人会的我不会=考挂。

    T1

    • 李煜东上有用kmp求最小循环节的例题,当初看了很久,所以……
    • 当然是选择Hash啦!
    • 时间复杂度不超过$Theta(NlogN)$。空间复杂度$Theta(N)$。
    #include<cstdio>
    #define ll long long
    using namespace std;
    int const N=1e6+5,p1=23333,p2=1313131,mod1=1e9+7,mod2=998244353;
    int n;
    ll ans;
    ll pre1[N],b1[N],pre2[N],b2[N];
    inline int read(){
        int ss(0),pp(1);char bb(getchar());
        for(;bb<48||bb>57;bb=getchar())if(bb=='-')pp=-1;
        while(bb>=48&&bb<=57)ss=(ss<<1)+(ss<<3)+(bb^48),bb=getchar();
        return ss*pp;
    }
    int main(){
        //freopen("1.in","r",stdin);
        //freopen("1.out","w",stdout);
        int T=read(),tp;
        b1[0]=b2[0]=1;
        for(register int i=1;i<N;++i)b1[i]=b1[i-1]*p1%mod1,b2[i]=b2[i-1]*p2%mod2;
        while(T--){
            ans=read()-1,n=read(),tp=1;
            ans*=n;
            register char bb=getchar(),la;
            while(bb<'A'||bb>'Z')bb=getchar();la=bb;
            for(register int i=1;i<=n;++i,bb=getchar()){
                pre1[i]=(pre1[i-1]*p1+bb)%mod1,pre2[i]=(pre2[i-1]*p2+bb)%mod2;
                if(bb!=la)tp=0;
            }
            if(tp){printf("%lld
    ",ans+n-1);continue;}
            if(!ans){
                register int i=n-1;
                for(;i;--i)
                    if(pre1[i]==(pre1[n]-pre1[n-i]*b1[i]%mod1+mod1)%mod1 
                    && pre2[i]==(pre2[n]-pre2[n-i]*b2[i]%mod2+mod2)%mod2)
                        break;
                printf("%d
    ",i);
                continue;
            }
            for(register int i=2,lt=n>>1;i<=lt;++i){
                if(n%i)continue;
                int bs1=pre1[i],bs2=pre2[i];
                for(register int j=i<<1;j<=n;j+=i)
                    if((pre1[j]-pre1[j-i]*b1[i]%mod1+mod1)%mod1!=bs1 
                    || (pre2[j]-pre2[j-i]*b2[i]%mod2+mod2)%mod2!=bs2)
                        goto ac;
                ans+=i*(n/i-1);break;
                ac:;
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    View Code

    T2

    • 65的大众分只得了15分。
    • 我的概率是真的垃圾。
    • 题解的思路稍不懂,打的迪哥的思路。
    • 求出每个点的先手胜率和从s开始用奇/偶数步到达每个点的概率。
    • 最大胜率是将自己引到胜率最大的点或将对手引到胜率最小的点得到的结果。
    • 平均胜率综合考虑所有情况即可。
    • 时空复杂度$Theta(N)$。
    #include<cstdio>
    #define ll long long
    using namespace std;
    int const N=1e5+5,M=3e5+5;
    int n,m,s;
    int head[N],Next[M],to[M],t;
    int rhc[N],du[N],rnxt[M],rto[M],rt;
    double win[N],al[N][2],tot,maxw,minw=2e9;
    double mx,av,ansx,ansv;
    inline int read(){
        int ss(0),pp(1);char bb(getchar());
        for(;bb<48||bb>57;bb=getchar())if(bb=='-')pp=-1;
        while(bb>=48&&bb<=57)ss=(ss<<1)+(ss<<3)+(bb^48),bb=getchar();
        return ss*pp;
    }
    inline void ad2(int x,int y){
        ++du[rto[++rt]=y];
        rnxt[rt]=rhc[x],rhc[x]=rt;
        return ;
    }
    inline void add(int x,int y){
        to[++t]=y;
        Next[t]=head[x],head[x]=t;
        return ad2(y,x);
    }
    inline double max(double x,double y){
        return x>y?x:y;
    }
    inline double min(double x,double y){
        return x<y?x:y;
    }
    int main(){
        //freopen("1.in","r",stdin);
        //freopen("1.out","w",stdout);
        n=read(),m=read(),al[s=read()][0]=1;
        for(register int i=1,ff,tt;i<=m;++i)
            ff=read(),tt=read(),add(ff,tt);
        scanf("%lf%lf",&mx,&av);
        for(register int i=n;i;--i){
            tot+=win[i];
            maxw=max(maxw,win[i]),minw=min(minw,win[i]);
            const double x=1.0-win[i];
            for(register int j=rhc[i];j;j=rnxt[j])
            win[rto[j]]+=x/(double)du[rto[j]];
        }
        for(register int i=1;i<=n;++i){
            const double on=al[i][0]/(double)du[i],jn=al[i][1]/(double)du[i];
            for(register int j=head[i];j;j=Next[j])
                al[to[j]][0]+=jn,al[to[j]][1]+=on;
        }
        double const swin=win[s];
        for(register int i=1;i<=n;++i){
            const double now=1.0/(double)(du[i]+1),nw=now*du[i],
            mxg=al[i][0]<al[i][1]?maxw:minw;
            ansx=max(ansx,
                 swin-al[i][0]*win[i]-al[i][1]*(1-win[i])
                 +al[i][0]*now*(1-mxg)+al[i][1]*now*mxg
                 +al[i][0]*nw*win[i]+al[i][1]*nw*(1-win[i]));
        }
        for(register int i=1;i<=n;++i){
            double now=1.0/(double)(du[i]+1),z=(tot-win[i])/(double)(n-1);
            ansv+=(1-(al[i][0]+al[i][1])*now)*swin+al[i][0]*now*(1-z)+al[i][1]*now*z;
        }
        printf("%.3lf %.3lf
    ",ansx,ansv/(double)n);
        return 0;
    }
    View Code

    T3

    • 考试想到了维护子树最大次大次次大的贡献,这样就可以做了。
    • 不过觉得稍毒瘤于是最后才去打,没打完……
    • 原本想用树链剖分,但题解给出了更优越的树上倍增。
    • 想到这些本题就不难解决了。
    • 时空复杂度$Theta(NlogN)$。
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #define ll long long
    #define mp make_pair
    using namespace std;
    int const N=2e5+5,M=4e5+5;
    int n,m,ans;
    int head[N],Next[M],to[M],t;
    int dep[N],Log[N],f[N][19],mx[N][19];
    pair<int,int>son[N][3];
    int par[N];
    inline int read(){
        int ss(0);char bb(getchar());
        while(bb<48||bb>57)bb=getchar();
        while(bb>=48&&bb<=57)ss=(ss<<1)+(ss<<3)+(bb^48),bb=getchar();
        return ss;
    }
    inline void add(int x,int y){
        to[++t]=y;
        Next[t]=head[x],head[x]=t;
        return ;
    }
    inline int max(int x,int y){
        return x>y?x:y;
    }
    int dfs(int x,int fa){
        int firs,firw=0,sces,scew=0,thrs,thrw=0,dnow=dep[x]+1;
        for(int i=head[x],y,z;i;i=Next[i])
            if((y=to[i])^fa){
                dep[y]=dnow,f[y][0]=x;
                for(register int j=0;j<Log[dnow];++j)
                    f[y][j+1]=f[f[y][j]][j];
                z=dfs(y,x);
                if(z>firw){
                    thrs=sces,thrw=scew;
                    sces=firs,scew=firw;
                    firs=y,firw=z;
                }
                else if(z>scew){
                    thrs=sces,thrw=scew;
                    sces=y,scew=z;
                }
                else if(z>thrw)
                    thrs=y,thrw=z;
            }
        ans=max(ans,firw+scew);
        son[x][0]=mp(firs,firw),son[x][1]=mp(sces,scew),son[x][2]=mp(thrs,thrw);
        return firw+1;
    }
    void redfs(int x,int fa){
        int anow=par[x]+1,gl=son[x][0].first,
        firw=son[x][0].second,secw=son[x][1].second;
        for(int i=head[x],y,dnow=dep[x]+1;i;i=Next[i])
            if((y=to[i])^fa){
                mx[y][0]=(y==gl?secw:firw);
                par[y]=max(anow,mx[y][0]+1);
                for(register int j=0;j<Log[dnow];++j)
                    mx[y][j+1]=max(mx[y][j],mx[f[y][j]][j]);
                redfs(y,x);
            }
        return ;
    }
    inline void _swap(int &x,int &y){
        int z=x;
        x=y,y=z;
        return ;
    }
    inline int lca(int x,int y){
        if(dep[x]<dep[y])_swap(x,y);
        int zans=son[x][0].second;
        for(register int i=Log[dep[x]];~i;--i)
            if(dep[f[x][i]]>=dep[y])zans=max(zans,mx[x][i]),x=f[x][i];
        if(x==y)return max(zans,par[x]);
        zans=max(zans,son[y][0].second);
        for(register int i=Log[dep[x]];~i;--i)
            if(f[x][i]^f[y][i])
                zans=max(zans,max(mx[x][i],mx[y][i])),
                x=f[x][i],y=f[y][i];
        int fa=f[x][0];
        zans=max(zans,par[fa]);
        if(son[fa][0].first!=x && son[fa][0].first!=y)return max(zans,son[fa][0].second);
        if(son[fa][1].first!=x && son[fa][1].first!=y)return max(zans,son[fa][1].second);
        return max(zans,son[fa][2].second);
    }
    int main(){
        //freopen("1.in","r",stdin);
        //freopen("1.out","w",stdout);
        n=read();
        Log[0]=-1;
        for(register int i=1,ff,tt;i<n;++i)
            Log[i]=Log[i>>1]+1,ff=read(),tt=read(),add(ff,tt),add(tt,ff);
        Log[n]=Log[n>>1]+1,dep[1]=1;
        dfs(1,0),ans=ans+2>>1;
        redfs(1,0);
        m=read();
        while(m--){
            int x=read(),y=read();
            if(x==y){printf("%d
    ",ans);continue;}
            printf("%d
    ",lca(x,y));
        }
        return 0;
    }
    View Code
  • 相关阅读:
    ACTION 的跳转与参数传递
    action 与 action 之间的跳转
    图片不存在时,显示一个默认的图片 (自己理解)
    java 防止表单重复提交(serlvet)
    java防止表单重复提交
    了解 Windows Azure 存储计费 – 带宽、事务和容量
    微软开放技术热烈祝贺开源社成立!
    “开源社”(开源联盟)成立
    Azure SQL 数据库的灵活缩放预览版简介
    通过 PowerShell 支持 Azure Traffic Manager 外部端点和权重轮询机制
  • 原文地址:https://www.cnblogs.com/remarkable/p/11710116.html
Copyright © 2020-2023  润新知