Subarrays OR

題目鏈接:Subarrays OR


我們以每個數字爲左端點的區間記錄答案。

顯然每個數字向右有效區間不超過30個,因爲每次有效區間肯定會多或上一個1。

所以暴力計算每一位二進制的位置,二分向後跳即可。


AC代碼:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=1e5+10;
int n,a[N];	vector<int> v[40],ans;
inline void solve(){
	cin>>n;	ans.clear();
	for(int i=0;i<31;i++)	v[i].clear();
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		for(int j=0;j<31;j++)	if(a[i]>>j&1)	v[j].push_back(i);
	}
	for(int i=0;i<31;i++)	v[i].push_back(1e9);
	for(int i=1;i<=n;i++){
		int now=a[i],pos=i;
		while(pos<=n){
			int mi=1e9;	ans.push_back(now);
			for(int j=0;j<31;j++)	if(!(now>>j&1)){
				int tmp=upper_bound(v[j].begin(),v[j].end(),pos)-v[j].begin();
				mi=min(mi,v[j][tmp]);
			}
			if(mi==1e9)	break;	pos=mi;
			now|=a[mi];
		}
	}
	sort(ans.begin(),ans.end()),ans.erase(unique(ans.begin(),ans.end()),ans.end());
	printf("%d\n",ans.size());
}
signed main(){
	int T;	cin>>T;	while(T--)	solve();
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章