• 20190818考试反思


      题不难,可我答的不够好。

      T1时间太长,忘了公式又推了半天。边码对拍边试公式,大概开考40分钟才A掉。

      T2想的太少,还是思路差一点拔高,大众分都能想到,应该能顺着想出来线段树思路。

      T3。。。。。因为给的时间过少,set建边不会,摸索半天,大概30分钟才把边建出来,然后打的时候发现我的dfs思路死了就剩10min了,立马想到他tarjan+topu,然后10分钟码完了撞了一个变量名,爆0了。

      这次考试大概比较简单,但是问题有

    1.线段树的运用不够灵活,一般是能够化出来一个式子,把和变量有关的放到一块,扔到树上,然后用常量进行判断修改查询等。

    2.T3有向图无向图搞混,这是不应该的,在确定要用图论来做的时候,先判断用哪部分知识。

      T1:裸catalan,没了。

    #include<iostream>
    #include<cstdio>
    using namespace std;
    const int N=2000020,mod=20100403;
    int fac[N],inv[N];
    inline int rd()
    {
        int s=0,w=1;
        char cc=getchar();
        for(;cc<'0'||cc>'9';cc=getchar()) if(cc=='-') w=-1;
        for(;cc>='0'&&cc<='9';cc=getchar()) s=(s<<3)+(s<<1)+cc-'0';
        return s*w;
    }
    int qpow(int a,int k)
    {
        int ans=1;
        for(;k;k>>=1,a=1ll*a*a%mod) if(k&1) ans=1ll*ans*a%mod;
        return ans;
    }
    int C(int n,int m)
    {
        if(n<m) return 0;
        return 1ll*fac[n]*inv[n-m]%mod*inv[m]%mod;
    }
    int main()
    {
        //freopen("data.in","r",stdin);
        //freopen("data.out","w",stdout);
        int n=rd(),m=rd();fac[0]=1;
        if(n<m) return puts("0"),0;
        for(int i=1;i<=n+m;i++) fac[i]=1ll*fac[i-1]*i%mod;
        inv[n+m]=qpow(fac[n+m],mod-2);
        for(int i=n+m;i>=1;i--) inv[i-1]=1ll*inv[i]*i%mod;
        printf("%d
    ",(C(n+m,n)-C(n+m,m-1)+mod)%mod);
    }
    /*
    g++ 1.cpp -o 1
    ./1
    4 3
    */
    View Code

      T2:线段树思路很顺利,不知为什么他们都沉迷于排序二分。暴力$O(nm)$很好打,考虑要优化哪部分,因为$O(m)$的部分每次都不一样,所以不优化它,考虑优化每一轮的计算,我们要的是一段能喝的权值和,只要排除不能喝的贡献即可,咋就不能喝了,$c[i]<ans+i$就不行了,就是当前的答案和这一轮他之前和他自己的消耗的次数,变量放一边$c[i]-i>=ans$为合法,只要区间最小值,然后如果都合法,那么直接加整个区间的贡献,否则对点挨个删,删到合法后加贡献,注意删完一个区间后边的排序就少一$c[i]-i$应该加一,然后就没了。每个点最多删一次,复杂度$O(nlogn)$

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N=100020;
    long long inf=0x7ffffffffffffff;
    long long f[N],a[N],c[N],w[N];
    struct tree{long long w,c,f,p;}tr[N*4];
    inline long long rd()
    {
        long long s=0,w=1;
        register char cc=getchar();
        for(;cc<'0'||cc>'9';cc=getchar()) if(cc=='-') w=-1;
        for(;cc>='0'&&cc<='9';cc=getchar()) s=(s<<3)+(s<<1)+cc-'0';
        return s*w;
    }
    inline void updata(int k)
    {
        tr[k].w=tr[k<<1].w+tr[k<<1|1].w;
        tr[k].c=min(tr[k<<1].c,tr[k<<1|1].c);
        if(tr[k<<1].c<=tr[k<<1|1].c) tr[k].p=tr[k<<1].p;
        else tr[k].p=tr[k<<1|1].p;
    }
    inline void modify(int k,int l,int r,int w){tr[k].c+=w;tr[k].f+=w;}
    inline void down(int k,int l,int r)
    {
        int mid=l+r>>1;
        modify(k<<1,l,mid,tr[k].f);
        modify(k<<1|1,mid+1,r,tr[k].f);
        tr[k].f=0;
    }
    void build(int k,int l,int r)
    {
        if(l==r)
        {
            tr[k].c=c[l]-l;
            tr[k].w=1;
            tr[k].p=l;
            return;
        }
        int mid=l+r>>1;
        build(k<<1,l,mid);build(k<<1|1,mid+1,r);
        updata(k);
    }
    void cut(int k,int l,int r,int id)
    {
        if(l==r){tr[k].w=0,tr[k].c=inf;return;}
        int mid=l+r>>1;
        if(tr[k].f)down(k,l,r);
        if(id<=mid) cut(k<<1,l,mid,id);
        else cut(k<<1|1,mid+1,r,id);
        updata(k);
    }
    void add(int k,int l,int r,int x,int y,int w)
    {
        if(l==x&&r==y){modify(k,l,r,w);return;}
        int mid=l+r>>1;
        if(tr[k].f) down(k,l,r);
        if(y<=mid) add(k<<1,l,mid,x,y,w);
        else if(x>mid) add(k<<1|1,mid+1,r,x,y,w);
        else add(k<<1,l,mid,x,mid,w),add(k<<1|1,mid+1,r,mid+1,y,w);
        updata(k);
    }
    int main()
    {
        int n=rd(),m=rd();
        long long x=rd();
        for(int i=1;i<=n;i++) w[i]=rd();
        for(int i=1;i<=n;i++) a[i]=rd();
        for(int i=1;i<=n;i++)
        {
            c[i]=(x-w[i])/a[i]+1;
            if(c[i]<0) c[i]=0;
        }
        build(1,1,n);
        long long ans=0;
        while(m--)
        {
            while(tr[1].c<ans)
            {
                int t=tr[1].p;
                cut(1,1,n,t);
                add(1,1,n,t,n,1);
            }
            ans+=tr[1].w;
        }
        printf("%lld
    ",ans);
    }
    /*
    g++ -std=c++11 2.cpp -o 2
    ./2
    5 2 20
    15 14 13 12 12
    1 1 1 1 1
    */
    View Code

      T3:sb题,正解$O(n^{2})$,我服了,最终还是看出来topu了,也打出来了,但是太紧张导致撞变量了。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N=100020;
    long long inf=0x7ffffffffffffff;
    long long f[N],a[N],c[N],w[N];
    struct tree{long long w,c,f,p;}tr[N*4];
    inline long long rd()
    {
        long long s=0,w=1;
        register char cc=getchar();
        for(;cc<'0'||cc>'9';cc=getchar()) if(cc=='-') w=-1;
        for(;cc>='0'&&cc<='9';cc=getchar()) s=(s<<3)+(s<<1)+cc-'0';
        return s*w;
    }
    inline void updata(int k)
    {
        tr[k].w=tr[k<<1].w+tr[k<<1|1].w;
        tr[k].c=min(tr[k<<1].c,tr[k<<1|1].c);
        if(tr[k<<1].c<=tr[k<<1|1].c) tr[k].p=tr[k<<1].p;
        else tr[k].p=tr[k<<1|1].p;
    }
    inline void modify(int k,int l,int r,int w){tr[k].c+=w;tr[k].f+=w;}
    inline void down(int k,int l,int r)
    {
        int mid=l+r>>1;
        modify(k<<1,l,mid,tr[k].f);
        modify(k<<1|1,mid+1,r,tr[k].f);
        tr[k].f=0;
    }
    void build(int k,int l,int r)
    {
        if(l==r)
        {
            tr[k].c=c[l]-l;
            tr[k].w=1;
            tr[k].p=l;
            return;
        }
        int mid=l+r>>1;
        build(k<<1,l,mid);build(k<<1|1,mid+1,r);
        updata(k);
    }
    void cut(int k,int l,int r,int id)
    {
        if(l==r){tr[k].w=0,tr[k].c=inf;return;}
        int mid=l+r>>1;
        if(tr[k].f)down(k,l,r);
        if(id<=mid) cut(k<<1,l,mid,id);
        else cut(k<<1|1,mid+1,r,id);
        updata(k);
    }
    void add(int k,int l,int r,int x,int y,int w)
    {
        if(l==x&&r==y){modify(k,l,r,w);return;}
        int mid=l+r>>1;
        if(tr[k].f) down(k,l,r);
        if(y<=mid) add(k<<1,l,mid,x,y,w);
        else if(x>mid) add(k<<1|1,mid+1,r,x,y,w);
        else add(k<<1,l,mid,x,mid,w),add(k<<1|1,mid+1,r,mid+1,y,w);
        updata(k);
    }
    int main()
    {
        int n=rd(),m=rd();
        long long x=rd();
        for(int i=1;i<=n;i++) w[i]=rd();
        for(int i=1;i<=n;i++) a[i]=rd();
        for(int i=1;i<=n;i++)
        {
            c[i]=(x-w[i])/a[i]+1;
            if(c[i]<0) c[i]=0;
        }
        build(1,1,n);
        long long ans=0;
        while(m--)
        {
            while(tr[1].c<ans)
            {
                int t=tr[1].p;
                cut(1,1,n,t);
                add(1,1,n,t,n,1);
            }
            ans+=tr[1].w;
        }
        printf("%lld
    ",ans);
    }
    /*
    g++ -std=c++11 2.cpp -o 2
    ./2
    5 2 20
    15 14 13 12 12
    1 1 1 1 1
    */
    View Code

     

  • 相关阅读:
    抽奖系统 random()
    JavaScript 稀奇的js语法
    Node初识笔记 1第一周
    vue 自定义指令
    vue 组件 单选切换控制模板 v-bind-is
    学习网址
    vue 组件 子向父亲通信用自定义方法用事件监听
    vue 组件 模板中根数据绑定需要指明路径并通信父
    vue 组件 模板input双向数据数据
    测试样式
  • 原文地址:https://www.cnblogs.com/starsing/p/11375000.html
Copyright © 2020-2023  润新知