zoukankan      html  css  js  c++  java
  • 20191019

    前言

    • B组题竟然没炸,开心= =
    • 主要是考完就放假心态很好。
    • 然而T1打挂了233。
    • 继续努力。

    T1

    • 正解神仙矩阵快速幂。
    • 然而好像都是把周期循环周期长度次,这样可以保证正确。
    • 代码很短。主要是这个题值域很小,所以最长不下降子序列的暴力复杂度$Theta(N^2)$变为了$Theta(150N)$,没必要打线段树或树状数组。
    • 时间复杂度$Theta(150len^2)$,空间复杂度$Theta(len^2)$,len是周期长度的平方。
    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    int const N=155;
    ll n,ans;
    int t,A,B,C,D,st,lit,zc;
    int a[110000],vis[N],bar[N];
    int main(){
        scanf("%lld%d%d%d%d%d",&n,&t,&A,&B,&C,&D);
        const int mod=D;
        for(register int i=1;i<=n;++i){
            if(vis[a[i]=t]){st=vis[t];lit=i-1;zc=i-vis[t];break;}
            vis[t]=i,t=(A*t*t+B*t+C)%mod;
        }
        if(!st)st=n+1;
        lit=min(n,1ll*lit+zc*zc);
        for(register int i=st+zc;i<=lit;++i)a[i]=a[i-zc];
        for(register int i=1,z,lt;i<st;++i){
            z=0,lt=a[i];
            for(register int j=0;j<=lt;++j)z=max(z,bar[j]);
            bar[lt]=++z,ans=max(ans,1ll*z);
        }
        for(register int i=st,z,lt;i<=lit;++i){
            z=0,lt=a[i];
            for(register int j=0;j<=lt;++j)z=max(z,bar[j]);
            bar[lt]=++z,ans=max(ans,(n-i)/zc+z);
        }
        printf("%lld",ans);
        return 0;
    }
    View Code

    T2

    • 正解神仙DP,稍不会。
    • 向zzn大神学习了同余系最短路。
    • 找出最小的体积,设为V。
    • 那么V的倍数肯定可以凑出,我们只需考虑凑出小于V的V种情况所需要的最小体积即可。
    • spfa跑最短路。注意需要满足题目中的限制。
    • 时间复杂度上界$Theta(kV^2)$,但实际远远达不到这个上界。
      空间复杂度$Theta(kV)$。
    • 其中k是spfa的常数。
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define ll long long
    int const N=1e4;
    int n,tot,m,l,c,mod=N,lit;
    int a[101];
    ll f[N];
    int lm[N];
    bool v[N];
    int q[10000000],t=1,u,x;
    template<class T>
    inline T read(){
        T 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 int min(int x,int y){
        return x<y?x:y;
    }
    int main(){
        n=read<int>(),m=read<int>();
        for(register int i=1;i<=n;++i)mod=min(mod,a[i]=read<int>());
        const int MOD=mod;
        l=read<int>(),c=read<int>();
        std::sort(a+1,a+n+1);
        for(register int i=1;i<=n;++i)
            if(a[i]!=a[i-1])a[++tot]=a[i];
        n=tot;
        for(lit=1;lit<=n&&a[lit]<l;++lit);--lit;
        memset(f,0x3f,MOD<<3),memset(lm,0x3f,MOD<<2);
        f[0]=lm[0]=0;
        while(u^t){
            v[x=q[++u]]=0;
            ll bs=f[x];
            for(register int i=1,y,la=lm[x],lnow=la+1,lt=min(n,c==lm[x]?lit:n);i<=lt;++i){
                y=(x+a[i])%MOD;
                if(f[y]>bs+a[i]){
                    f[y]=bs+a[i];
                    if(i>lit)lm[y]=lnow;
                    if(!v[y])v[q[++t]=y]=1;
                }
                else if(f[y]==bs+a[i]){
                    if(i>lit && lm[y]>lnow){
                        lm[y]=lnow;
                        if(!v[y])v[q[++t]=y]=1;
                        continue;
                    }
                    else if(i<=lit && lm[y]>=lnow){
                        lm[y]=la;
                        if(!v[y])v[q[++t]=y]=1;
                    }
                }
            }
        }
        while(m--){
            ll w=read<ll>();
            puts(f[w%MOD]<=w?"Yes":"No");
        }
        return 0;
    }
    View Code

    T3

    • 本场考试最简单的题目竟然在T3……
    • 线段树维护dfs序即可。
    • 更新时向上标记。如果当前点在之前被更新过直接停止,这样保证每个点只被更新一次。
    • 然后这个题就没了。
    • 时间复杂度$Theta(NlogN)$,空间复杂度$Theta(N)$。
    • 但考试的时候我却打了一个半小时才打完。
    • 原因是我将被修改成黑点的点的父链又单独考虑了一遍,需要树链剖分+树状数组。
    • 所以代码会很长……
    #include<cstdio>
    #define L tr[k].lc
    #define R tr[k].rc
    using namespace std;
    int const N=1e5+5,M=2e5+5;
    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;
    }
    int n,m;
    int head[N],Next[M],to[M],t;
    int val[N];
    bool vis[N];
    int l[N],r[N],tot;
    int siz[N],son[N],fa[N],dep[N],top[N];
    int blk;
    struct node{
        int lc,rc,w,f;
    }tr[N<<2];
    int BIT[N];
    inline void add(int x,int y){
        to[++t]=y;
        Next[t]=head[x],head[x]=t;
        return ;
    }
    int dfs1(int x,int y){
        for(int i=head[x],nw=0,dnow=dep[x]+1,z;i;i=Next[i])
            if((z=to[i])^y){
                dep[z]=dnow,fa[z]=x;
                siz[x]+=dfs1(z,x);
                if(siz[z]>nw)nw=siz[z],son[x]=z;
            }
        return ++siz[x];
    }
    void dfs2(int x,int y){
        l[x]=++tot,top[x]=y;
        if(!son[x]){r[x]=tot;return ;}
        dfs2(son[x],y);
        for(int i=head[x],sw=son[x],fw=fa[x];i;i=Next[i])
            if(to[i]!=sw && to[i]!=fw)dfs2(to[i],to[i]);
        r[x]=tot;
        return ;
    }
    void build(int x,int y,int k){
        L=x,R=y;
        if(x==y)return ;
        int mid=x+y>>1;
        return build(x,mid,k<<1),build(mid+1,y,k<<1|1);
    }
    inline int max(int x,int y){
        return x>y?x:y;
    }
    inline void down(int k){
        int lk=k<<1,rk=lk|1,z=tr[k].f;
        tr[k].f=0;
        tr[lk].w=max(z,tr[lk].w),tr[lk].f=max(z,tr[lk].f);
        tr[rk].w=max(z,tr[rk].w),tr[rk].f=max(z,tr[rk].f);
        return ;
    }
    inline int ask(int x,int k){
        while(L^R){
            if(tr[k].f)down(k);
            if(x<=(L+R>>1))k<<=1;
            else k=k<<1|1;
        }
        return tr[k].w;
    }
    void getmax(int x,int y,int z,int k){
        tr[k].w=max(z,tr[k].w);
        if(L>=x&&R<=y){tr[k].f=max(z,tr[k].f);return ;}
        int mid=L+R>>1;
        if(x<=mid)getmax(x,y,z,k<<1);
        if(y>mid)getmax(x,y,z,k<<1|1);
        return ;
    }
    inline void change(int x,int y){
        while(x<=n)BIT[x]+=y,x+=x&-x;
        return ;
    }
    inline int query(int x){
        int ans=0;
        while(x)ans+=BIT[x],x-=x&-x;
        return ans;
    }
    inline void update(int x){
        int fx=fa[top[x]];
        while(fx)change(l[top[x]],1),change(l[x]+1,-1),x=fx,fx=fa[top[x]];
        return change(1,1),change(l[x]+1,-1);
    }
    inline void modify(int x){
        while(!vis[x]){
            if(l[fa[x]]<l[x])getmax(l[fa[x]],l[x]-1,val[fa[x]],1);
            if(r[fa[x]]>r[x])getmax(r[x]+1,r[fa[x]],val[fa[x]],1);
            vis[x]=1,x=fa[x];
        }
        return ;
    }
    int main(){
        //freopen("lca2.in","r",stdin);
        //freopen("1.out","w",stdout);
        n=read(),m=read();
        for(register int i=1;i<=n;++i)val[i]=read();
        for(register int i=1,ff,tt;i<n;++i)
            ff=read(),tt=read(),add(ff,tt),add(tt,ff);
        dfs1(1,0),dfs2(1,1);
        build(1,n,1),vis[1]=1;
        while(m--){
            char bb=getchar();
            while(bb^'Q'&&bb^'M')bb=getchar();
            int x=read();
            if(bb=='Q'){
                if(blk)printf("%d
    ",query(l[x])?max(val[x],ask(l[x],1)):ask(l[x],1));
                else puts("-1");
                continue;
            }
            update(x),blk=1;
            getmax(l[x],r[x],val[x],1);
            modify(x);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Python 去掉文本中空行
    Pandas常用操作方法
    Numpy常用操作方法
    Python获取指定路径下所有文件的绝对路径
    Python获取指定目录下所有子目录、所有文件名
    Pycharm选中代码无法Backspace直接删除
    Redis常用命令(一)
    在eclipse程序中设置的断点上有一个斜杠,正常启动debug不能够跳转到debug页面,怎么解决
    常见的几种网络广告模式
    struts2中拦截器与过滤器的区别
  • 原文地址:https://www.cnblogs.com/remarkable/p/11713763.html
Copyright © 2011-2022 走看看