51nod 1674 区间的价值 V2(暴力)

基准时间限制:1 秒 空间限制:131072 KB 分值: 40  难度:4级算法题
 收藏
 关注
lyk拥有一个区间。
它规定一个区间的价值为这个区间中所有数and起来的值与这个区间所有数or起来的值的乘积。
例如3个数2,3,6。它们and起来的值为2,or起来的值为7,这个区间对答案的贡献为2*7=14。
现在lyk有一个n个数的序列,它想知道所有n*(n+1)/2个区间的贡献的和对1000000007取模后的结果是多少。

例如当这个序列为{3,4,5}时,那么区间[1,1],[1,2],[1,3],[2,2],[2,3],[3,3]的贡献分别为9,0,0,16,20,25。
Input
第一行一个数n(1<=n<=100000)。
接下来一行n个数ai,表示这n个数(0<=ai<=10^9)。
Output
一行表示答案。
Input示例
3
3 4 5
Output示例
70
相关问题
区间的价值 
160
alpq654321  (题目提供者)
C++ 11的运行时限为:1000 ms ,空间限制为:131072 KB  示例及语言说明请按这里

 允许其他 AC 的用户查看此代码,分享代码才能查看别人的代码并有机会获得勋章


与运算规定该位为0,则包含该位的所有区间这一位对答案的贡献为0,所以我们每次找到该位为1的

一段连续区间,或运算就好算了,该区间内的数中只要有数的该位为1,则计入贡献就好了。

#include<set>
#include<map>   
#include<stack>          
#include<queue>          
#include<vector>  
#include<string>
#include<math.h>          
#include<stdio.h>          
#include<iostream>          
#include<string.h>          
#include<stdlib.h>  
#include<algorithm> 
#include<functional>  
using namespace std;          
#define ll long long       
#define inf  1000000000     
#define mod 1000000007           
#define maxn  100005
#define lowbit(x) (x&-x)          
#define eps 1e-9
int a[maxn],b[35];
ll ans;
int read()
{  
    char ch;  
    int n = 0;  
    ch = getchar();  
    while(ch >= '0' && ch <= '9'){  
        n = n * 10 + ch - '0';  
        ch = getchar();  
    }  
    return n;  
}  
int main(void)
{
	int i,j,k,n;
	n=read();
	for(i=1;i<=n;i++)
		a[i]=read();
	for(i=0;i<31;i++)
	{
		int l=1,r,num=(1<<i);
		while(1)
		{
			for(;l<=n;l++)
				if(a[l]&num)
					break;
			if(l>n) 
				break;
			for(r=l+1;r<=n;r++)
				if(!(a[r]&num))
					break;
			r--;
			for(j=0;j<31;j++)
				b[j]=0;
			for(j=l;j<=r;j++)
				for(k=0;k<31;k++)
				{
					if(a[j]&(1<<k))
						b[k]=j;
					if(b[k])
					{
						ans+=(ll)num*(b[k]-l+1)%mod*((1<<k)%mod);
						ans%=mod;
					}
					if(ans<0)
						ans+=mod;
				}
			l=r+1;
		}
	}
	printf("%lld\n",ans);
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值