P17729 [SCP-J 2026] 进位 / carry题解
sword7level · · 题解
题意:
给定一个长度为
题目分析:
首先我们定义
由于
我们不难想到转移就是从两点之间进位刚好为
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=5e5+10,mod=998244353;
int t,n;
ll dp[N],a[N];
inline ll read(){
ll w=0,f=1;
char ch=getchar();
while(ch<'0' || '9'<ch){
if(ch=='-') f=-1;
ch=getchar();
}
while('0'<=ch && ch<='9'){
w=(w<<3)+(w<<1)+(ch^48);
ch=getchar();
}
return w*f;
}
signed main(){
cin.tie(0);cout.tie(0);
//ios::sync_with_stdio(false);
t=read();
while(t--){
n=read();
for(int i=1;i<=n;i++) a[i]=read(),dp[i]=0;
dp[0]=0;
int l=1,r=1;
ll popl=0,popr=0,suml=0,sumr=0;
for(int i=1;i<=n;i++){
ll x=a[i];
int px=__builtin_popcountll(x);
suml+=x;popl+=px;
while(l<=i){
int c=popl-__builtin_popcountll(suml);
if(c<=1) break;
ll y=a[l];
suml-=y;popl-=__builtin_popcountll(y);
l++;
}
sumr+=x;popr+=px;
while(r<=i){
ll y=a[r];
ll nsum=sumr-y;
ll npop=popr-__builtin_popcountll(y);
ll nc=npop-__builtin_popcountll(nsum);
if(nc>=1){
sumr=nsum;
popr=npop;
r++;
}else break;
}
int R=0;
int cr=popr-__builtin_popcountll(sumr);
if(cr>=1) R=r;
else R=0;
ll ways=1;
if(l<=R){
ways+=(dp[R]-dp[l-1]);
ways%=mod;
if(ways<0) ways+=mod;
}
dp[i]=dp[i-1]+ways;
if(dp[i]>=mod) dp[i]-=mod;
}
cout<<dp[n]<<'\n';
}
return 0;
}