code forces 1030E Vasya and Good Sequences
阿新 • • 發佈:2018-12-13
思路: 如果區間[ L, R ] 想要滿足good ,那麼充分必要條件就是 1 [ L, R ] 的每一位1 的個數和是偶數, 2 [ L, R ]中的二進位制1 最多的一個數的1 的個數的2倍不能超過sum 。 那麼一個 longlong 的數,二進位制1 最多 64 (1e18 62),那麼我只要向前列舉到他的二倍就可以了,剩下的我可以用 字首和來轉移。 odd[ i ] 表示 [1,x] (x<=i) 的二進位制和為奇數的數量。even 同理
程式碼:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N =3e5+5; int even[N]; int odd[N]; int sum[N]; int n; int a[N]; int zhuan(ll x) { int cnt=0; while(x) { if(x%2) cnt++; x/=2; } return cnt; } int main() { scanf("%d",&n); ll x; for(int i=1;i<=n;i++) { scanf("%lld",&x); a[i]=zhuan(x); } ll ans=0; even[0]=1; for(int i=1;i<=n;i++) { sum[i]=sum[i-1]+a[i]; int mx=a[i]; for(int j=i-1;j>=max(i-128,1);j--) { mx=max(mx,(int)a[j]); int ss=sum[i]-sum[j-1]; if(ss%2==0&&mx*2<=ss) { ans++; } } if(i>129) { if(sum[i]&1)ans+=1ll*odd[i-130]; else ans+=1ll*even[i-130]; } odd[i]=odd[i-1]+(sum[i]%2==1); even[i]=even[i-1]+(sum[i]%2==0); } printf("%lld\n",ans); return 0; }