• Codeforces Round #627 (Div. 3)


    A 只有判段相邻的差是不是有奇数,有奇数NO,反之YES

    B 因为题目说随便两个相等+另一个数就是YES,所以map存第一次出现的数字的位置,如果再次出现,只要那个数的第一个位置不是i-1就是YES反之NO

    C 蛋疼题意,其实只要找两个RR之间最短的距离+1就行了

    D

    题意:

    老师的n个想法价值ai,同学的n个想法价值bi,相互对应,找一共有多少对 ai+aj-bi-bj>0

    思路:
    直接将老师的思路减学生的思路,从小到大排序,用upper_bound去找他的相反数的大一点的位置,复杂度是O(lgn*n)

    但是n是2e5的范围,答案可能会爆int,别忘了开ll

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define ull unsigned long long
    #define il inline
    #define it register int
    #define inf 0x3f3f3f3f
    #define lowbit(x) (x)&(-x)
    #define pii pair<int,int>
    #define mak(n,m) make_pair(n,m)
    #define mem(a,b) memset(a,b,sizeof(a))
    #define mod 998244353
    const int maxn=2e5+10;
    int a[maxn],b;
    int main(){
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
            scanf("%d",&a[i]);
        for(int i=0;i<n;i++) {
            scanf("%d",&b);
            a[i]-=b;
        }
        sort(a,a+n);
        ll ans=0;
        for(int i=0;i<n;i++){
            int zhi=-a[i];
            int pos=upper_bound(a+i+1,a+n,zhi)-a;
            ans+=(ll)n-pos;
        }
        printf("%lld
    ",ans);
        return 0;
    }

    E

    题意(题目描述进行魔改,但内容大致不变):

    给n,h,l,r 四个值,表示n长度的数组,0~h-1的范围,在【l,r】区间得分能获得一个奖品(1<=n<=2000)

    接下来的n个数,是按顺序的比赛得分,但是你有一个权力,每次得分可以保持不变,或者减一,然后进行累加,如果超出h,%h,问最多有多少奖品

    思路:

    dp【i】【j】,i表示第i个数字,j表示前面减了几次一;

    cc数字i 全部累加情况(无减一)- j,这里有一个坑就是cc可能小于0,一定要while(cc<0)cc+h;而不是(cc+h)%h,因为这个h可能过小。//u1s1,比赛的时候如果写出,也会在这里被hack,因为惯性思维下意识写了(cc+h)%h

    状态转移方程就是

    k=(l<=cc && r>=cc);

    dp[i][j]=max(dp[i-1][j-1]+k,dp[i-1][j]+k); (当j==0的时候特判一下,因为没有-1这种

    最后比较max(dp【n】【i】0<=i<=n)中

    #include<iostream>
    #include<map>
    #include<set>
    #include<queue>
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define ull unsigned long long
    #define il inline
    #define it register int
    #define inf 0x3f3f3f3f
    #define lowbit(x) (x)&(-x)
    #define pii pair<int,int>
    #define mak(n,m) make_pair(n,m)
    #define mem(a,b) memset(a,b,sizeof(a))
    #define mod 998244353
    const int maxn=2e3+10;
    int n,m,t,h,l,r;
    int a[maxn],dp[maxn][maxn];
    int zhi[maxn][2];
    int main(){
        scanf("%d%d%d%d",&n,&h,&l,&r);
        int ans=0,c=0;mem(dp,0);
        for(it i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        for(it i=1;i<=n;i++){
            c+=a[i];c%=h;
            if(l<=c && r>=c){
                dp[i][0]=dp[i-1][0]+1;
            }
            else{
                dp[i][0]=dp[i-1][0];
            }
            for(it j=1;j<=i;j++){
                int cc=(c-j+h)%h;while(cc<0){cc+=h;}
                if(l<=cc && r>=cc){
                    dp[i][j]=max(dp[i-1][j-1]+1,dp[i-1][j]+1);
                }
                else{
                    dp[i][j]=max(dp[i-1][j-1],dp[i-1][j]);
                }
            }
        }
        for(int i=0;i<=n;i++){
            ans=max(dp[n][i],ans);
        }
        printf("%d
    ",ans);
        return 0;
    }

    F

     题意:

    树上每个点要么黑色要么白色

    假设每个点为根的话,求这个点的所有子树里面最大的白点-黑点

    思路:

    先确定1为根结点,dfs从叶子结点往上递归,叶子结点白为1,黑为-1,其他节点看子节点累加上来大于0的加,小于0的就不加了

    如果把每个点看成根,其实就是把它的父节点当成子节点,原本第一次dfs把所有子节点弄个好了,父结点因为受到这个点的影响,可能变大,可能为0或者不变,所以从1这个根结点往下遍历,求这个点的子节点对自己的影响的其他部分,在子节点加上,便是答案。

    #include<iostream>
    #include<map>
    #include<set>
    #include<queue>
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define ull unsigned long long
    #define il inline
    #define it register int
    #define inf 0x3f3f3f3f
    #define lowbit(x) (x)&(-x)
    #define pii pair<int,int>
    #define mak(n,m) make_pair(n,m)
    #define mem(a,b) memset(a,b,sizeof(a))
    #define mod 998244353
    const int maxn=2e5+10;
    vector<int>g[maxn];
    int a[maxn],n,dp[maxn],ans[maxn];
    void dfs1(int root,int fa){
        dp[root]=a[root];
        for(auto &i:g[root]){
            if(i==fa){continue;}
            dfs1(i,root);
            dp[root]+=max(0,dp[i]);
        }
    }
    void dfs2(int root,int fa,int zhi){
        ans[root]=dp[root]+zhi;
        for(auto &i:g[root]){
            if(i==fa){continue;}
            dfs2(i,root,max(ans[root]-max(dp[i],0),0));
        }
    }
    int main(){
        scanf("%d",&n);
        for(it i=1;i<=n;i++){
            scanf("%d",&a[i]);if(!a[i]){a[i]=-1;}
        }
        for(it i=1;i<n;i++){
            int u,v;
            scanf("%d%d",&u,&v);
            g[u].push_back(v);
            g[v].push_back(u);
        }
        dfs1(1,0);
        dfs2(1,0,0);
        for(it i=1;i<=n;i++){
            printf(i==n?"%d
    ":"%d ",ans[i]);
        }
        return 0;
    }
  • 相关阅读:
    在一个字符串中找到第一个只出现一次的字符
    查找最小的k个数
    动规:最大上升子序列
    平衡二叉树
    【笔记】php和mysql结合 搞了一个表出来
    设计模式心得(既设计模式篇终章):描述设计模式时的通用公式
    分享系列 之 linux IO原理与几种零拷贝机制的实现
    近期分享:BIO 与 NIO 的实质区别到底是什么?
    源码阅读笔记 之 ThreadLocal —— 不复杂,却有点绕的一个 per thread API
    小脑袋瓜充满了问号:为什么AMQP可以叫做 Advanced?JMS就要low一等吗?
  • 原文地址:https://www.cnblogs.com/luoyugongxi/p/12488050.html
Copyright © 2020-2023  润新知