• Codeforces Round #510 Div. 2 Virtual Participate记


      这场打的顺手到不敢相信。如果不是vp的话估计肯定打不到这个成绩。

      A:最大显然,最小的话每次暴力给最小的+1。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    #define N 110
    int n,m,a[N],mx,s;
    int main()
    {
    /*#ifndef ONLINE_JUDGE
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
    #endif*/
        n=read(),m=read();
        for (int i=1;i<=n;i++) a[i]=read(),s=max(s,a[i]);
        s+=m; 
        for (int i=1;i<=m;i++)
        {
            int mx=1;
            for (int j=2;j<=n;j++) if (a[j]<a[mx]) mx=j;
            a[mx]++;
        }
        int mx=1;for (int i=1;i<=n;i++) mx=max(mx,a[i]);
        cout<<mx<<' '<<s; 
        return 0;
    }
    View Code

      B:每种蔬菜集合取最小值,枚举选哪些即可。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    #define N 1010
    int n,ans=700000000,f[8];
    struct data{int x,y;
    }a[N];
    int main()
    {
    /*#ifndef ONLINE_JUDGE
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
    #endif*/
        n=read();for (int i=1;i<8;i++) f[i]=ans;
        for (int i=1;i<=n;i++)
        {
            a[i].x=read();
            char c=getchar();
            while (c<'A'||c>'Z') c=getchar();
            while (c>='A'&&c<='Z')
            {
                a[i].y+=1<<c-'A';
                c=getchar();
            }
            f[a[i].y]=min(f[a[i].y],a[i].x);
        }
        for (int i=0;i<8;i++)
            for (int j=0;j<8;j++)
                for (int k=0;k<8;k++)
                if ((i|j|k)==7) ans=min(ans,f[i]+f[j]+f[k]);
        if (ans==700000000) cout<<-1;
        else cout<<ans;    
        return 0;
    }
    View Code

      C:显然就是取一些数使乘积最大。讨论一下各种情况。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    #define N 200010
    int n,a[N];
    int main()
    {
    /*#ifndef ONLINE_JUDGE
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
    #endif*/
        n=read();
        int cnt=0;
        for (int i=1;i<=n;i++)
        {
            a[i]=read();
            cnt+=a[i]<0;
        }
        int last=0;
        if (cnt%2==0)
        {
            int cnt=0;
            for (int i=1;i<=n;i++)
            if (a[i]==0)
            {
                cnt++;
                if (last) printf("%d %d %d
    ",1,last,i);
                last=i;
            }
            if (last&&cnt<n) printf("%d %d
    ",2,last);
            last=0;
            for (int i=1;i<=n;i++)
            if (a[i]!=0)
            {
                if (last) printf("%d %d %d
    ",1,last,i);
                last=i;
            }
        }
        else
        {
            int mx=0,cnt=0;
            for (int i=1;i<=n;i++)
            if (a[i]<0&&(!mx||a[i]>a[mx])) mx=i;
            for (int i=1;i<=n;i++)
            if (a[i]==0) cnt++,printf("%d %d %d
    ",1,i,mx);
            if (cnt<n-1) printf("%d %d
    ",2,mx);
            last=0;
            for (int i=1;i<=n;i++)
            if (a[i]!=0&&i!=mx)
            {
                if (last) printf("%d %d %d
    ",1,last,i);
                last=i;
            }
        }
        return 0;
    }
    View Code

      D:前缀和后即每次询问有多少个数与x的和小于y。随便拿个数据结构维护一下,感觉treap比较方便。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    #define N 200010
    #define ll long long
    #define lson tree[k].ch[0]
    #define rson tree[k].ch[1]
    int n,root,cnt=0;
    ll m,a[N],ans;
    struct data{ll x;int p,ch[2],s;
    }tree[N];
    void up(int k){tree[k].s=tree[lson].s+tree[rson].s+1;}
    void move(int &k,int p)
    {
        int t=tree[k].ch[p];
        tree[k].ch[p]=tree[t].ch[!p],tree[t].ch[!p]=k,up(k),up(t),k=t;
    }
    void ins(int &k,ll x)
    {
        if (k==0){k=++cnt;tree[k].x=x,tree[k].s=1,tree[k].p=rand();tree[k].ch[0]=tree[k].ch[1]=0;return;}
        tree[k].s++;
        if (x<tree[k].x) {ins(lson,x);if (tree[lson].p>tree[k].p) move(k,0);}
        else {ins(rson,x);if (tree[rson].p>tree[k].p) move(k,1);}
    }
    ll query(int k,ll s)
    {
        if (k==0) return 0;
        if (tree[k].x>s) return query(lson,s);
        else return query(rson,s)+tree[lson].s+1;
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
    #endif
        cin>>n>>m;m--;
        srand(20020509);
        for (int i=1;i<=n;i++) a[i]=a[i-1]+read();
        ins(root,0);
        for (int i=1;i<=n;i++)
        {
            ans+=i-query(root,a[i]-m-1);
            ins(root,a[i]);
        }
        cout<<ans;
        return 0;
    }
    View Code

      E:从小到大倒退期望即可。每次需要知道某格子到其他小于他的格子的距离平方之和,显然横纵坐标可以分别计算,然后展开即可维护。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    #define N 1010
    #define P 998244353
    int n,m,s,sum,Sum[2],Sqr[2],Cnt[2];
    int ksm(int a,int k)
    {
        int s=1;
        for (;k;k>>=1,a=1ll*a*a%P) if (k&1) s=1ll*s*a%P;
        return s;
    }
    int trans(int x,int y){return (x-1)*m+y;}
    struct data{int x,y,v,ans;
    }a[N*N];
    bool cmp(const data&a,const data&b)
    {
        return a.v<b.v;
    }
    void update(int k,int x,int p)
    {
        a[k].ans=(a[k].ans+1ll*x*x%P*Cnt[p]%P+Sqr[p]-2ll*x*Sum[p]%P+P)%P;
    }
    void ins(int x,int p)
    {
        Cnt[p]++;Sum[p]=(Sum[p]+x)%P;Sqr[p]=(Sqr[p]+1ll*x*x%P)%P;
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
    #endif
        n=read(),m=read();
        for (int i=1;i<=n;i++)
            for (int j=1;j<=m;j++)
            a[trans(i,j)].x=i,a[trans(i,j)].y=j,a[trans(i,j)].v=read();
        int x=read(),y=read();s=trans(x,y);
        sort(a+1,a+n*m+1,cmp);
        for (int i=1;i<=n*m;i++)
        {
            int t=i;
            while (t<n*m&&a[t+1].v==a[i].v) t++;
            for (int j=i;j<=t;j++)
            {
                a[j].ans=sum;
                update(j,a[j].x,0),update(j,a[j].y,1);
                a[j].ans=1ll*a[j].ans*ksm(i-1,P-2)%P;
            }
            for (int j=i;j<=t;j++)
            {
                ins(a[j].x,0),ins(a[j].y,1);
                sum=(sum+a[j].ans)%P;
            }
            i=t;
        }
        for (int i=1;i<=n*m;i++)
        if (trans(a[i].x,a[i].y)==s) {cout<<a[i].ans;return 0;}
    }
    View Code

      F:想了半天觉得一点也不可做,于是大力贪心,莫名其妙就过了。设f[i]为i子树内划分集合的最少数量,g[i]为i子树中这些集合的最大深度的最小值。dp时贪心地合并各子树内最大深度最小的那些集合,即把小的合并在一块,大的不管了。并没有想清楚为什么对。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    #define N 1000010
    int n,m,p[N],degree[N],deep[N],fa[N],f[N],g[N],b[N],root,t=0;
    struct data{int to,nxt;
    }edge[N<<1];
    void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
    void dp(int k)
    {
        bool flag=1;
        for (int i=p[k];i;i=edge[i].nxt)
        if (edge[i].to!=fa[k]) flag=0,dp(edge[i].to);
        if (flag) f[k]=1,g[k]=0;
        for (int i=p[k];i;i=edge[i].nxt)
        if (edge[i].to!=fa[k]) f[k]+=f[edge[i].to];
        int cnt=0;
        for (int i=p[k];i;i=edge[i].nxt) 
        if (edge[i].to!=fa[k]) b[++cnt]=g[edge[i].to]+1;
        sort(b+1,b+cnt+1);
        if (cnt) g[k]=b[1];
        for (int i=1;i<cnt;i++)
        if (b[i]+b[i+1]<=m) f[k]--,g[k]=b[i+1];
    }
    void dfs(int k)
    {
        for (int i=p[k];i;i=edge[i].nxt)
        if (edge[i].to!=fa[k])
        {
            fa[edge[i].to]=k;
            deep[edge[i].to]=deep[k]+1;
            dfs(edge[i].to);
        }
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
    #endif
        n=read(),m=read();
        for (int i=1;i<n;i++)
        {
            int x=read(),y=read();
            addedge(x,y),addedge(y,x);
            degree[x]++,degree[y]++;
        }
        for (int i=1;i<=n;i++) if (degree[i]>1) {root=i;break;}
        dfs(root);
        dp(root);
        cout<<f[root];
        return 0;
    }
    View Code

      result:rank 5

  • 相关阅读:
    Maven+SpringMVC+Mybatis 开发环境整合
    在子jsp页面中调用父jsp中的function或父jsp调用子页面中的function
    动态库的生成和调用
    怎么下载纯净版系统
    ATL开发COM组件
    链表问题
    内存理解
    静态绑定和动态绑定;位拷贝和值拷贝
    导EXCEL单表单方法
    mfc解决回车键默认关闭窗口的一般方法
  • 原文地址:https://www.cnblogs.com/Gloid/p/9822423.html
Copyright © 2020-2023  润新知