每日一题 5.25 小AA的数列

小AA的数列

https://ac.nowcoder.com/acm/problem/14414

这一题我是只想到暴力的 t了后面想到了以前写的一些题就算了二进制的前缀和
但还是t了 于是在学习了一番博客后 我学会了
我们先统计二进制前缀和 然后在统计前缀和的奇偶数的前缀和 因为要统计长度为偶数
所有是以二一跳的前缀和 有了这以后 我们枚举左端点 就可以O(1)求右端点以及贡献
对于范围lr 就从把1n改为lr

#include <bits/stdc++.h>
#define ll long long
const int N=1e5+5;
const int p=1e9+7;
using namespace std;
int n,l,r,a[N],b[N],f[N][31],dp[N][31][2];
int main()
{
    ios::sync_with_stdio(false);
    cin>>n>>l>>r;
    for(int i=1;i<=n;++i)cin>>a[i];
    for(int i=1;i<=n;++i)
    {
        for(int j=29;j>=0;--j)
        {
            f[i][j]=f[i-1][j]+((a[i]>>j)&1);///二进制前缀和
            if(i!=1)
            {
                dp[i][j][0]=dp[i-2][j][0];///以二一跳的奇偶数前缀和
                dp[i][j][1]=dp[i-2][j][1];
            }
            ++dp[i][j][f[i][j]&1];///当前是奇是哦
        }
    }
    ll ans=0;
    for(int i=1;i<=n;++i)///枚举左端点
    {
        int L=i+l-1,R=min(i+r-1,n);///最短与最长区间长度
        if((L-i+1)&1){///不能提前处理 l r
            ++L;
        }
        if((R-i+1)&1){
            --R;
        }
        if(L>R) continue;
        for(int j=29;j>=0;--j)
        {
            int k=((f[i-1][j]&1)^1);///相反位数  本来是奇 求偶数个数
            ll ins=dp[R][j][k];
            if(L!=1)
            {
                ins-=dp[L-2][j][k];
            }
            ans+=(ins*(1<<j))%p,ans%=p;///算贡献
        }
     //   cout<<ans<<endl;
    }
    cout<<ans<<endl;
    return 0;
}
每日一题题解 文章被收录于专栏

每日一题题解的汇集

全部评论

相关推荐

rndguy:个人思路,抛砖引玉。 要我的话我先问清楚需求:要什么精度,什么速度,什么环境。 如果精度要求很低,平台也有点柔性的话,只需要输出pwm,然后开个中断记录各多少个脉冲,如果脉冲时间不对齐了就反馈控制电流加减就行。要求同步要求稍微高点的话可以在脉冲间做个线性插值,同步精度会高些。 但总体来说,如果直流有刷只有脉冲没有好的编码器的话很难做精准定位什么的(除非用一些电机磁路结构相关的奇技淫巧如高频注入什么的),所以要求更高就需要大量参数辨识和校准,那就慢多了。
点赞 评论 收藏
分享
做个有文化的流氓:不想当将军的士兵不是好士兵
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务