• 2020牛客暑期多校(六)


    https://ac.nowcoder.com/acm/contest/5671

    Binary Vector(数学)

    题意:求$frac{2^n-1}{2^n}$

    代码来自:https://blog.nowcoder.net/n/1d9a191e486649fd8c7c62de021d322a?f=comment

    #include<bits/stdc++.h>
    using namespace std;
    const long long mod=1e9+7;
    long long a[20000010],x=5e8+4,y=5e8+4;
    int main()
    {
        int n,t,i;
        a[1]=5e8+4;
        for(i=2;i<=2e7;i++)
        {
            x=x*y%mod;
            a[i]=(a[i-1]-a[i-1]*x)%mod+mod;
        }
        for(i=2;i<=2e7;i++) a[i]^=a[i-1];
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            printf("%lld
    ",a[n]);
        }
        return 0;
    }

    解释:

    解释

    K-Bag(DP)

    题意:判断一个数组是不是K-Bag。K-Bag为由1~K的permutation的任意长度重复的子集。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=5e5+7;
    unordered_map<int,int>mp;
    ll a[N],f[N];//f:可能为断点的地方=1 
    int main(){
        int t;
        scanf("%d",&t);
        while(t--){
            mp.clear();
            memset(f,0,sizeof(f));
            int n;int k;
            scanf("%d%d",&n,&k);
            int flag=0,cnt=0;
            f[0]=1;//位置0可能是一个断点。 
            for(int i=1;i<=n;++i){
                scanf("%d",&a[i]);
                if(a[i]>k) flag=1;
            }
            if(flag) {printf("NO
    ");continue;}
            for(int i=1;i<=n;++i){
                if(i>k){
                    mp[a[i-k]]--;
                    if(mp[a[i-k]]==0) cnt--;
                }
                if(mp[a[i]]==0) cnt++;
                mp[a[i]]++;
                if(cnt==k||cnt==i) f[i]=(i-k>0)?f[i-k]:1;
                /* 
                如果cnt==k,说明包括a[i]的前面k个数字满足一个k-bag
                那么此时i是不是断点,取决于在这k个数字之前的几个区间
                满不满足k-bag,所以转移掉
                cnt==k必然有i-k>0
                如果cnt==i,那么说明是有可能
                不完整的最前面一段满足数字都不相等。
                那么我们set此处为1,因为这里有成为断点的可能。 
                如果中间某处失败成为一个断点,那么此时不会赋值为1
                那么这个原本可能是断点的位置的下一个位置就算成功也不会赋值1
                所以到最后都满足要求的断点,只会在最后k个中出现
                前面的即使=1也不算数 
                */ 
            }
            mp.clear(); cnt=0;
            for(int i=n;i>=max(0,n-k);--i){
                /*
                只遍历最后一段,检查最后一段是否正确
                */
                if(cnt==n-i&&f[i]){flag=1;break;}
                if(mp[a[i]]==0) cnt++;
                mp[a[i]]++;
            }
            if(flag) printf("YES
    ");
            else printf("NO
    ");
        }
    }
  • 相关阅读:
    ARM与MIPS平台优劣对比分析
    ARM11Linux2.6ButtonDriverBaseinfo1
    程序员都应该阅读的十一本名书
    驱动设计ARM(6410)按键驱动0基础知识点
    创业编程七个错误认识
    ARM11Linux2.6ButtonDriverBaseinfo
    Arm设计思想与高效C语言编程联系
    个人软件已死?
    评价一个软件的3个角度
    我对北理FTP联盟的建议
  • 原文地址:https://www.cnblogs.com/rainartist/p/13400032.html
Copyright © 2020-2023  润新知