• Educational Codeforces Round 19


    A. k-Factorization

    题目大意:给一个数n,求k个大于1的数,乘积为n。(n<=100,000,k<=20)

    思路:分解质因数呗

    #include<cstdio>
    #define MN 100000
    int a[MN+5],an;
    int main()
    {
        int n,k,i;
        scanf("%d%d",&n,&k);
        for(i=2;k>1&&n>1;++i)for(;k>1&&n%i==0;--k,n/=i)a[++an]=i;
        if(n==1)return 0*puts("-1");
        for(i=1;i<=an;++i)printf("%d ",a[i]);printf("%d",n);
    }

    B. Odd sum

    题目大意:给你n个数,求和为奇数的子序列的最大和。(n<=10^5)

    思路:大于0的偶数直接加入答案,把奇数排序,先选一个最大的把它删掉并加入答案,while剩下的最大的的两个奇数和大于0就加入答案并删掉。

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    char B[1<<26],*S=B,C;int X,F;
    inline int read()
    {
        for(F=1;(C=*S++)<'0'||C>'9';)if(C=='-')F=-1;
        for(X=C-'0';(C=*S++)>='0'&&C<='9';)X=(X<<3)+(X<<1)+C-'0';
        return X*F;
    }
    #define MN 100000
    int a[MN+5],an;
    int main()
    {
        fread(B,1,1<<26,stdin);
        int n=read(),i,x,ans=0;
        for(i=1;i<=n;++i)
            if((x=read())&1)a[++an]=x;
            else if(x>0)ans+=x;
        sort(a+1,a+an+1);
        ans+=a[an];
        for(i=an;--i>1;--i)if(a[i]+a[i-1]>0)ans+=a[i]+a[i-1];else break;
        printf("%d",ans);
    }

    C. Minimal string

    题目大意:给出一个序列的入栈顺序,求字典序最小的可能的出栈顺序。(序列长度<=10^5)

    思路:堆+双向链表贪心,选了一个元素后之后只能选这个元素的前一个元素和后面的元素,每次选能选的最小且位置最前的。

    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    #define MN 100000
    char s[MN+5];
    int ls[MN+5],nx[MN+5],u[MN+5];
    struct node
    {
        char c;int x;
        bool operator<(const node&b)const{return c==b.c?x>b.x:c>b.c;}
    };
    priority_queue<node> pq;
    int main()
    {
        int n,i,l,x;
        scanf("%s",s+1);n=strlen(s+1);
        for(i=1;i<=n;++i)ls[i]=i-1,nx[i]=i+1,pq.push((node){s[i],i});
        for(i=l=1;i<=n;++i)
        {
            while((x=pq.top().x)<l||u[x])pq.pop();
            u[x]=1;putchar(pq.top().c);pq.pop();
            if(ls[x]<l&&ls[x])pq.push((node){s[ls[x]],ls[x]});
            l=ls[x];nx[ls[x]]=nx[x];ls[nx[x]]=ls[x];
        }
    }

    D. Broken BST

    题目大意:给出一棵n个节点的树,每一个点有一个权值,对每个点的权值从根节点开始按二叉搜索树的方式查询,问有多少个点的权值不会被查到。(n<=10^5)

    思路:dfs求出会走到每个节点的数字区间。

    #include<cstdio>
    #include<map>
    using namespace std;
    char B[1<<26],*S=B,C;int X,F;
    inline int read()
    {
        for(F=1;(C=*S++)<'0'||C>'9';)if(C=='-')F=-1;
        for(X=C-'0';(C=*S++)>='0'&&C<='9';)X=(X<<3)+(X<<1)+C-'0';
        return X*F;
    }
    #define MN 100000
    #define MX 1000000000
    int v[MN+5],l[MN+5],r[MN+5],d[MN+5];
    map<int,int> mp;
    void dfs(int x,int L,int R)
    {
        if(x<0)return;
        if(L<=v[x]&&v[x]<=R)mp[v[x]]=1;
        if(L<v[x])dfs(l[x],L,min(R,v[x]-1));
        if(R>v[x])dfs(r[x],max(L,v[x]+1),R);
    }
    int main()
    {
        fread(B,1,1<<26,stdin);
        int n=read(),i,ans=0;
        for(i=1;i<=n;++i)v[i]=read(),
            (l[i]=read())>0?++d[l[i]]:0,
            (r[i]=read())>0?++d[r[i]]:0;
        for(i=1;i<=n;++i)if(!d[i])dfs(i,0,MX);
        for(i=1;i<=n;++i)if(!mp[v[i]])++ans;
        printf("%d",ans);
    }

    E. Array Queries

    题目大意:给出n和ai(1<=i<=n),一次变换定义为把p变成p+a[p]+k,q次询问,每次给出p和k,问要多少次能把p变成大于n的数。(n,q<=10^5)

    思路:分块,对于k<=n^0.5直接预处理出各个p和k的答案,对于k>n^0.5答案最大不会超过n^0.5,直接暴力,复杂度O(n^1.5)。

    #include<cstdio>
    inline int read()
    {
        int x;char c;
        while((c=getchar())<'0'||c>'9');
        for(x=c-'0';(c=getchar())>='0'&&c<='9';)x=(x<<3)+(x<<1)+c-'0';
        return x;
    }
    #define MN 100000
    #define MK 350
    int a[MN+5],f[MK+5][MN+5];
    int main()
    {
        int n=read(),q,i,k,ans;
        for(i=1;i<=n;++i)a[i]=read();
        for(k=1;k<=MK;++k)for(i=n;i;--i)f[k][i]=i+a[i]+k>n?1:f[k][i+a[i]+k]+1;
        for(q=read();q--;)
        {
            i=read();k=read();
            if(k<=MK)printf("%d
    ",f[k][i]);
            else{for(ans=0;i<=n;i+=a[i]+k)++ans;printf("%d
    ",ans);}
        }
    }

    F. Mice and Holes

    题目大意:n只老鼠m个洞分别位于数轴上,每个洞有容量ci,求每个老鼠都进洞的最小距离和。(n,m<=5,000)

    思路:把老鼠和洞分别排序,最优方案下进每个洞的老鼠必然是连续的区间,f[i][j]表示前i个洞进前j只老鼠的最小距离和,s[i][j]表示前j只老鼠都进第i个洞的距离和,f[i][j]=min(f[i-1][k]+s[i][j]-s[i][k])(j-k<=ci),单调队列维护即可,复杂度O(nm)。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define MN 5000
    struct hole{int p,c;}h[MN+5];
    bool cmp(hole a,hole b){return a.p<b.p;}
    int x[MN+5],q[MN+5],ql,qr;
    ll f[MN+5][MN+5],s[MN+5];
    inline int z(int x){return x<0?-x:x;}
    int main()
    {
        int n,m,i,j;ll cnt=0;
        scanf("%d%d",&n,&m);
        for(i=1;i<=n;++i)scanf("%d",&x[i]);
        for(i=1;i<=m;++i)scanf("%d%d",&h[i].p,&h[i].c),cnt+=h[i].c;
        if(cnt<n)return 0*puts("-1");
        sort(x+1,x+n+1);sort(h+1,h+m+1,cmp);
        memset(f,42,sizeof(f));f[0][0]=0;
        for(i=1;i<=m;++i)for(q[ql=1,qr=0]=j=0;j<=n;++j)
        {
            s[j]=s[j-1]+z(h[i].p-x[j]);
            while(ql<=qr&&f[i-1][j]-s[j]<=f[i-1][q[qr]]-s[q[qr]])--qr;q[++qr]=j;
            while(j-q[ql]>h[i].c)++ql;
            f[i][j]=f[i-1][q[ql]]+s[j]-s[q[ql]];
        }
        printf("%I64d",f[m][n]);
    }
  • 相关阅读:
    TensorFlow学习笔记1:graph、session和op
    TensorFlow学习笔记2:逻辑回归实现手写字符识别
    Tensorflow学习笔记3:卷积神经网络实现手写字符识别
    Firstpython介绍
    Oracle sql语句学习
    总结__window dns域名解析错误及其解决方法
    Group By 和 Having, Where ,Order by语句的执行顺序
    Oracle 语句分类
    webbrowser自动登录,没有点击事件,不是submit提交按钮的情况下如何模拟点击登录
    webbrowser跨域访问iframe中的元素实现自动登录
  • 原文地址:https://www.cnblogs.com/ditoly/p/ECR19.html
Copyright © 2020-2023  润新知