zoukankan      html  css  js  c++  java
  • 2019牛客暑期多校第一场题解ABCEFHJ

    A.Equivalent Prefixes

    传送门

    题意:给你两个数组,求从第一个元素开始到第p个元素 满足任意区间值最小的元素下标相同的 p的最大值。

    题解:我们可以从左往右记录到i为止每个区间的最小值有哪些,因为每个值都是不一样的,对于当前的 i 如果1~i中每个区间最小值数量相同那么下标肯定也会相同,否则记录的值的数量就会不同,我们可以用单调栈记录目前为止每个区间的“最小值”的下标,栈里面元素数量不同时肯定不满足条件。

    代码:

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N = 1e5 + 10;
    int a[N],b[N],u[N],v[N];
    int main() {
        int n;
        while(~scanf("%d",&n)) {
            for (int i = 1; i <= n; i++) scanf("%d",&a[i]);
            for (int i = 1; i <= n; i++) scanf("%d",&b[i]);
            int i,cnt1=0,cnt2=0;
            for ( i = 1; i <= n; i++) {
                while (cnt1 && a[i] < a[u[cnt1]]) cnt1--;
                u[++cnt1] = i;
                while (cnt2 && b[i] < b[v[cnt2]]) cnt2--;
                v[++cnt2] = i;
                if (cnt1 != cnt2) break;
            }
            printf("%d
    ", i-1);
        }
        return 0;
    }
    View Code

    B.Integration

    传送门

    题意:已知输出

    题解:

     

    参考博客: https://blog.csdn.net/mmk27_word/article/details/96450520

          https://www.cnblogs.com/yanlifneg/p/11211455.html#commentform

    代码: 

    #include <cstdio>
    #include <cstring>
    #define ll long long
    using namespace std;
    const int N = 1000 + 10;
    const ll mod = 1e9 + 7;
    ll a[N],b[N];
    ll qp(ll a,ll b) {
        ll ans = 1;
        a%=mod;
        while(b) {
            if (b&1) ans = ans * a % mod;
            a = a * a % mod;
            b >>= 1;
        }
        return ans;
    }
    int main() {
        int n;
        while(~scanf("%d",&n)) {
            for (int i = 0; i < n; i++)
                scanf("%lld",&a[i]);
            ll ans = 0;
            for (int i = 0; i < n; i++) {
                b[i] = 2 * a[i] % mod;
                for (int j = 0; j < n; j++)
                    if (i != j) b[i] = b[i] * ((a[j]*a[j]-a[i]*a[i])%mod) %mod;
                b[i] = qp(b[i],mod-2);
                ans = ((ans + b[i]) % mod + mod) % mod;
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    View Code

    C.Euclidean Distance

    传送门

    题意:在一个n维坐标系里面有个点A(a1/m,a2/m,...,an/m),在坐标系中找到一个点P(p1,p2,...,pn)满足pi>0且∑ni=1 pi =1,求满足条件的P到A的

    最小欧几里得距离ni=1​ (ai/mpi)^2

    题解:为了方便计算我们可以先约去m最后再将结果除以m^2,就成了求∑ni=1​ (aipi)^2 /m^2,∑ni=1 pi =m。显然我们减小数值大的ai的值比减小值小的ai更优。

    我们先将ai排序,为了使得最大值更小,我们可以每次把最大值更新到与下一个值相同大小。我们初始化能更新到的数组长度num = n,可以用来减小ai的值have = m。

    如果have的值能够将前i个元素更新为a[i+1]则更新;否则num更新为i,剩余的have平分到前num个元素上,此时前num个元素的值都是a[num]-have/num。剩下的n-num个元素值为ai。

    此时∑ni=1​ (aipi)^2 /m^2 =(num*(a[num]-have/num)^2+∑ni=num+1a[i]^2)/m^2。

    代码:

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N = 1e4 + 10;
    const int M = 70;
    const ll mod = 1e9 + 7;
    int a[N];
    int main() {
        int n,m;
        while(~scanf("%d%d",&n,&m)) {
            for (int i = 1; i <= n; i++) {
                scanf("%d",&a[i]);
            }
            sort(a+1,a+n+1,greater<int>());
            int num = n,have = m;
            for (int i = 1; i < n; i++) {
                if (i* (a[i]-a[i+1])<= have)
                    have -= i*(a[i]-a[i+1]);
                else {
                    num = i;
                    break;
                }
            }
            ll fm = 1ll * num * m * m;
            ll fz = (1ll*a[num]*num - have) * (1ll*a[num]*num - have) ;
            for (int i = num+1; i <= n; i++)
                fz += 1ll*num*a[i]*a[i];
            ll tf = __gcd(fz,fm);
            fz/=tf;fm/=tf;
            if (fm == 1 ) printf("%lld
    ", fz);
            else printf("%lld/%lld
    ", fz,fm);
        }
        return 0;
    }
    View Code

     

    E:ABBA

    传送门

    题意:有一个长度2(n+m)的字符串,它可以被分解成n个AB,m个BA,问有多少种符合条件的字符串,答案% 10^9+7

    题解:贪心,我们先用AB的A,再用BA的B,B同理。我们可以用dp[i][j]表示用了i个A和j个B组成合法序列的方案数,因为我们先用AB的A(AB有n个),再用BA的A,所以A的数量最多可以有B的数量+n个,当A的数量没这么多时可以在字符串中加个A,即 if (i-j<n) dp[i+1][j] = (dp[i+1][j]+dp[i][j])%mod; B同理。

     代码:

    #include <cstdio>
    #include <cstring>
    #define ll long long
    using namespace std;
    const int N = 2000 + 10;
    const ll mod = 1e9 + 7;
    ll dp[N][N];
    int main() {
        int n,m;
        while(~scanf("%d%d",&n,&m)) {
             for (int i = 0; i <= n+m; i++)
                for (int j = 0; j <= n+m; j++) dp[i][j] = 0;
            dp[0][0] = 1;
            for (int i = 0; i <= n+m; i++)
                for (int j = 0; j <= n+m; j++) {
                    if (i-j<n) dp[i+1][j] = (dp[i+1][j]+dp[i][j])%mod;
                    if (j-i<m) dp[i][j+1] = (dp[i][j+1]+dp[i][j])%mod;
                }
            printf("%lld
    ",dp[n+m][n+m]);
        }
        return 0;
    }
    View Code

    F:Random Point in Triangle

    传送门

    题意:在△ABC中任选一个点P,P与A、B、C三点相连,求最大的面积的期望E = max{S△PBC,S△APC,S△ABP} * 36的结果。

    题解:E= 11/36 * S△ABC => 36E = 11 S△ABC

    证明参考:https://www.cnblogs.com/WAautomaton/p/11211864.html

    代码:

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    int main() {
        ll x1,x2,x3,y1,y2,y3;
        while(~scanf("%lld%lld%lld%lld%lld%lld",&x1,&y1,&x2,&y2,&x3,&y3))
            printf("%lld
    ", abs(11*(x1*y2+x2*y3+x3*y1-x1*y3-x3*y2-x2*y1)));
        return 0;
    }
    View Code

    H.XOR

    传送门

    题意:给你一个有n个元素的集合a,问a的异或和为0的所有子集的元素数量和。

    题解:我们可以转化为求每个数能异或为0的贡献。这里要用到线性基 <--- 推荐博客。

       我们先求集合a的线性基A,A中元素数量为r,对于线性基外n-r个元素,任选一个还剩n-r-1个,那么这n-r个元素每个的贡献为2^(n-r-1);

     然后我们考虑线性基内的元素x,我们对剩下n-1个数求线性基,避免超时我们先对线性基A外的n-r个元素求线性基B,然后在计算线性基A内各个元素x的贡献时,将B数组赋值给C再将A内其他元素加入C内,如果x加不进则求x的贡献。

    代码:

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N = 1e5 + 10;
    const int M = 70;
    const ll mod = 1e9 + 7;
    ll a[N],b[N],A[M],B[M],C[M];
    bool add(ll arr[],ll x) {
        for (int i = 63; i >= 0; i--) {
            if (x & (1ll<<i)) {
                if (arr[i]) x^=arr[i];
                else {
                    arr[i] = x;
                    return true;
                }
            }
        }
        return false;
    }
    ll qp(ll y){
        ll ans = 1,x = 2;
        while(y) {
            if (y&1) ans = ans*x%mod;
            x = x * x % mod;
            y>>=1;
        }
        return ans;
    }
    int main() {
        int n;
        while(~scanf("%d",&n)) {
            memset(A,0,sizeof(A));
            memset(B,0,sizeof(B));
            int r = 0;
            for (int i = 0; i < n; i++) {
                scanf("%lld",&a[i]);
                if (add(A,a[i])) b[r++] = a[i];
                else add(B,a[i]);
            }
            if (r == n) {
                printf("0
    ");
                continue;
            }
            ll ans = (n-r) * qp(n-r-1) %mod;
            for (int i = 0; i < r; i++) {
                for (int j = 0; j <= 63; j++) C[j] = B[j];
                for (int j = 0; j < r; j++)
                    if (i!=j) add(C,b[j]);
                if (!add(C,b[i])) ans = (ans + qp(n-r-1)) % mod;
            }
            printf("%lld
    ", ans);
        }
        return 0;
    }
    View Code

    J.Fraction Comparision

    传送门

    题意:比较x/a和y/b的大小关系。

    题解:因为 0≤ x,10^18,所以我们可以先比较整数部分,当整数部分相同时再把余数交叉相乘比较大小。

    代码:

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N = 64 + 10;
    int main() {
        ll x,y,a,b;
        while(~scanf("%lld%lld%lld%lld",&x,&a,&y,&b)) {
            ll t1 = x/a, t2 = y/b;
            if (t1 < t2) printf("<
    ");
            else if (t1 > t2) printf(">
    ");
            else {
                t1 = x%a*b;
                t2 = y%b*a;
                if (t1 < t2) printf("<
    ");  
                else if (t1 > t2) printf(">
    ");
                else if (t1 == t2) printf("=
    ");
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    HTML颜色表
    SQL 语法参考手册
    色环[微软MSDN]
    网页配色方案及方法[网上配色文章集合
    驰骋工作流程引擎公文流程引擎图片演示VSTO技术
    工作流程引擎手机应用方寸之间尽在掌握。
    关于流程的退回与撤消
    驰骋.net工作流程引擎设计开发讲座: 工作流程类型模式
    驰骋工作流程引擎,工作流程管理系统,工作流程中间件, 支持日历面板,采用vsto技术处理公文类的流程流转。
    驰骋.net工作流程引擎,工作流程管理系统定时启动约定
  • 原文地址:https://www.cnblogs.com/l999q/p/11279400.html
Copyright © 2011-2022 走看看