zoukankan      html  css  js  c++  java
  • [XDFZ集训Day1]NOI2020模拟1

    [XDFZ集训]NOI2020模拟

    假的NOI模拟,真的CSP-J模拟

    T1 :Stone

    小D 正在玩取石子游戏。
    小D 共有n 堆石子,依次编号为1, 2, · · · , n,其中第i 堆有ai 颗石子。
    小D 每次会等概率随机选择一颗石子,并取完它所在的那一堆石子。
    小D 想要知道,第1 堆石子被取走的时间的期望。如果你不知道期望是什么,你
    可以把它理解为所有情况下,这堆石子被取走的时间的平均数。
    但是小D 并不会,请你帮帮他。
    n<=1e5

    是个人都会做到期望题

    E = 1 + ∑ ai / (a1+ai)

    直接考虑新加一个的概率即可

    正式题解:

     代码:

    #include<bits/stdc++.h>
     
    using namespace std;
     
    #define LL long long
     
    inline int read()
    {
        int f = 1,x = 0;
        char ch;
        do
        {
            ch = getchar();
            if(ch == '-') f = -1;
        }while(ch<'0'||ch>'9');
        do
        {
            x = (x<<3) + (x<<1) + ch - '0';
            ch = getchar();
        }while(ch>='0'&&ch<='9');
        return f*x;
    }
     
    const int MAXN = 1e5 + 10;
     
    int n;
    int a[MAXN];
    //bitset<MAXN>a;
    LL sum;
    bool flag2 = 0;
    double dp[MAXN],dsum                                                                                                                    ;
    double ans = 0;
     
    int main()
    {
        n = read();
        for(int i=1;i<=n;i++)
        {
            a[i] = read();sum+=a[i];
            if(a[i] != 1)  flag2 = 1;
        }
        if(!flag2)
        {
            dp[1] = a[1] * 1.0/ sum;
            dsum += dp[1];
            for(int i=2;i<=n;i++)
            {
                dp[i] = (1.0 - dsum)/(n-i+1);
                dsum += dp[i];
            }
            for(int i=1;i<=n;i++)
            {
                ans += dp[i] * i;
            }
            printf("%.6f
    ",ans);
            return 0;
        }
        ans = 0;
        for(int i=2;i<=n;i++)
        {
            ans += 1.0*a[i]/(a[i]+a[1]);
        }
        printf("%.6f
    ",ans+1);
    }

    T2:memory

    小D 正在研究信息在内存中的存储。
    小D 共有n 条信息,依次编号为1, 2, · · · , n,第i 条信息的大小为ai。
    小D 可以将这些信息分为连续的k 组,每组存入一个内存单元,每组需要的存
    储空间为这组中所有信息大小之和。
    小D 可以使用压缩技术将每条信息的大小同时从ai 变为(ai + x) mod m,其中
    x 为一个小D 自己选定的整数。
    小D 想要知道,这k 组信息需要的存储空间最大值最小可以是多少。
    但是小D 并不会,请你帮帮他。
    n<=1e5

    直接贴题解:

    事实上,直接倒序就可以A了,万恶卡常,100 --》 70

    代码:

    #include<bits/stdc++.h>
     
    using namespace std;
     
    #define LL long long
    #define re register
     
    inline int read()
    {
        int f = 1,x = 0;
        char ch;
        do
        {
            ch = getchar();
            if(ch == '-') f = -1;
        }while(ch<'0'||ch>'9');
        do
        {
            x = (x<<3) + (x<<1) + ch - '0';
            ch = getchar();
        }while(ch>='0'&&ch<='9');
        return f*x;
    }
     
    const int MAXN = 100000 + 10;
     
    int n,m,k;
    LL a[MAXN],b[MAXN];
    LL ans,sum;
     
    inline bool check(int x)
    {
           LL tot = 0,val = 0;
        for(re int i=1;i<=n;i++) if(b[i]>x) return false;
        for(re int i=1;i<=n;i++)
        {
            if(val + b[i] > x)
            {
                val = b[i];
                tot++;
            }
            else val += b[i];
        }
        if(val) tot++;
        return tot <= k;
    }
     
    inline LL solve()
    {
        int l = 1,r = ans-1;
        int res = 0;
        while(r>=l)
        {
            int mid = (l+r)>>1;
            if(check(mid))
            {
            //  if(mid == 6)
            //  {
            //      for(int i=1;i<=n;i++) cout << b[i] << " ";
            //      exit(0);
            //  }
                r = mid - 1;
                res = mid;
            }
            else l = mid + 1;
        }
        //cout << res << endl;
        return res;
    }
     
    int main()
    {
        srand(time(NULL));
        n = read(),m = read(),k = read();ans = 1<<30;
        for(re int i=1;i<=n;i++) a[i] = read();
        for(re int i=m;i>=0;i--)
        {
            sum = 0;
            for(re int j=1;j<=n;j++)
            {
                b[j] = (a[j] + i)%m,sum+=b[j];if(b[j]>ans) continue;
            }
        //  for(int j=1;j<=n;j++) cout << b[j] << " ";
        //  cout << endl;
            if(!check(ans-1)) continue;
            ans = min(ans , solve()); 
        }
        cout << ans << endl;
    }

    T3 :subset

    小D 正在研究集合。
    小D 想要知道,对于给定的n,有多少个集合{1, 2, · · · , n} 的子集满足最大公约
    数为1,而最小公倍数为n。
    但是小D 并不会,请你帮帮他。因为答案可能很大,所以你只要输出这样的子集
    个数对998244353 取模的结果即可。
    n<=1e18

    不会,直接贴题解:

  • 相关阅读:
    ubuntu16.04设置开机自启服务
    Flask架构管理及特点(重要)
    Django开发框架知识点
    Django进行数据迁移时,报错:(1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(6) NOT NULL)' at line 1")
    Java 网络编程(二) 两类传输协议:TCP UDP
    Java 网络编程(一) 网络基础知识
    .NET开源项目
    手写ArrayList、LinkedList
    命令查看java的class字节码文件
    dubbo总结
  • 原文地址:https://www.cnblogs.com/wlzs1432/p/12018657.html
Copyright © 2011-2022 走看看