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\n",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\n");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\n");
        else printf("NO\n");
    }
}

 

posted @ 2020-07-29 22:23  IcecreamArtist  阅读(72)  评论(0编辑  收藏  举报