51nod 40 interval value V2 bit operation + enumeration

The meaning of the question: the value of defining an interval is: the value of the AND number in this interval * the value of the OR operation of the number in this interval.
n<=1e5,a[i]<=1e9 . Find the sum of all interval values ​​of the sequence a and % 1e9 +7.


Fix L, increase R, the result of AND operation is non-increasing, and the result of OR operation is non-decreasing. And change log(max(a[i]))=32 times at most.
It is convenient for simulation to use vector d[j] to record binary If the jth bit is a subscript of 1, to find the change value of a[i], you only need to enumerate j, and bisect the first subscript larger than i in d[j].

Take i as the left endpoint to find the right endpoint simulation of the two operation changes respectively..O(n*log^2(a[i]))

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+5,mod=1e9+7,M=32;
ll n,a[N];
vector<ll> d[M],e[M];
intmain()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		for(int j=0;j<M;j++)
			if((a[i]>>j)&1)
				d[j].push_back(i);
			else
				e[j].push_back(i);
	}
	ll res=0;
	for(int i=1;i<=n;i++)
	{
		vector<ll> b,c;
		for(int j=0;j<M;j++)
		{
			if(!((a[i]>>j)&1))
			{
				int idx=lower_bound(d[j].begin(),d[j].end(),i)-d[j].begin();
				if(idx<d[j].size())
					b.push_back(d[j][idx]);
			}
			else
			{
				int idx=lower_bound(e[j].begin(),e[j].end(),i)-e[j].begin();
				if(idx<e[j].size())
					c.push_back(e[j][idx]);				
			}
		}
		sort(b.begin(),b.end());
		sort(c.begin(),c.end());
		b.erase(unique(b.begin(),b.end()),b.end());
		c.erase(unique(c.begin(),c.end()),c.end());
		
		ll j=0,p=0,yu=a[i],huo=a[i],ls=i;
		while(j<b.size()&&p<c.size())
		{
			if(b[j]>c[p])
			{
				res = (res + ((huo * yu)% mod * (c [p] -ls))% mod)% mod;		
				yu&=a[c[p]];
				ls=c[p];
				p++;
			}
			else
			{
				res = (res + ((huo * yu)% mod * (b [j] -ls))% mod)% mod;
				huo|=a[b[j]];
				ls=b[j];
				j++;
			}
		}
		while(j<b.size())
		{
			res = (res + (((yu * huo)% mod) * (b [j] -ls))% mod)% mod;
			huo|=a[b[j]];
			ls=b[j];
			j++;
		}
		while(p<c.size())
		{
			res = (res + (((yu * huo)% mod) * (c [p] -ls))% mod)% mod;
			yu&=a[c[p]];
			ls=c[p];
			p++;
		}
		if(ls<=n)
			res = (res + ((n-ls + 1) * ((yu * huo)% mod))% mod)% mod;
	}
	printf("%lld\n",res);
	return 0;
}
mark..click to open the link

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326401890&siteId=291194637