Problem - 1333C - Codeforces 前缀和,Counting Arrays

126 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 23 天,点击查看活动详情

Problem - 1333C - Codeforces 前缀和

自己想的是把不好的数组全找出来一减就可以了,但发现有点复杂,之后发现已经过了很长时间了,就去看题解了,,,

直接去找好的数组就可以,可以发现遍历到i时,以i为新数组的右端点,前面和为0区间的最大的左端点作为新数组的左端点maxl,可以发现这个左端点maxl+1到i区间和为0,然后数组个数就是i-(maxl+1)+1-1,减1是为了把maxl+1减掉,因为加上这个区间和就是0了,如果sum这个值之前出现过那么就看看maxl是否还满足是前面和为0区间的最大的左端点,不是就更新成最大值,一开始maxl=-1是为了符合初始的情况

C. Eugene and an array (区间为0前缀和处理)__Rikka_的博客-CSDN博客

int n,a[200005];
map<int,int>mp;
signed main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    //freopen("in.txt","r",stdin);
    cin>>n;
    int sum=0,ans=0,maxl=-1;
    mp[0]=0;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        sum+=a[i];
        if(mp[sum]||sum==0)
        {
            maxl=max(maxl,mp[sum]);
        }
        ans+=i-maxl-1;
        mp[sum]=i;
    }
    cout<<ans<<endl;
    return 0;
}
//

Counting Arrays 

可以求出不符合条件的个数然后用总数减去就可以,可以发现每个序列都一定至少会有一种,这种就是每次都选位置1,考虑别的情况,可以发现对于每一个a[i]和任意的j属于[2,n],都有gcd(a[i],j)>1的话就是不符合情况的,那么a[i]就需要是2~n中质数的乘积的倍数才可以,那这个种数是好求的,对于1个数k,他的倍数就是mk\left \lfloor \frac{m}{k} \right \rfloor,对于每一个i所能选的数也就确定了,之后累加起来用总数减去就是答案,因为要的是下取整的结果所以m/k直接算就可以不用取模了(为了这玩意看了快一个小时,,)

Educational Codeforces Round 138 (Rated for Div. 2) A - E - 知乎 (zhihu.com)

int pri[1000006],cnt,n,m;
bool ispri[1000006];
void is_pri(int n)
{
    memset(ispri,1,sizeof(ispri));
    for(int i=2;i<=n;i++)
    {
        if(ispri[i]) pri[++cnt]=i;
        for(int j=1;j<=cnt&&i*pri[j]<=n;j++)
        {
            ispri[i*pri[j]]=0;
            if(i%pri[j]==0) break;
        }
    }
}
signed main()
{
    //ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    //freopen("in.txt","r",stdin);
    cin>>n>>m;
    is_pri(1000000);
    int mul=1,ans=0,lcm=1;
    for(int i=1;i<=n;i++)
    {
        if(ispri[i]) lcm=lcm*i;
        if(lcm>m) break;
        int tmp=m/lcm%mod;
        mul=mul*tmp%mod;
        ans=(ans+mul)%mod;
    }
    int poww=1,res=0;m%=mod;
    for(int i=1;i<=n;i++)
    {
        poww=poww*m%mod;
        res=(res+poww)%mod;
    }
    ans=(res-ans+mod)%mod;
    cout<<ans<<endl;
    return 0;
}
//