码迷,mamicode.com
首页 > 其他好文 > 详细

1674 区间的价值 V2(分治)

时间:2017-09-14 21:33:36      阅读:173      评论:0      收藏:0      [点我收藏+]

标签:不同   family   return   fine   show   div   define   closed   alt   

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

 

 

//想不到啊,还以为能找贡献水过呢。一种解法是分治,一段区间内,最多有 loga 种不同的 与,或 的值,将区间分半,对后半段统计与或值的个数,再对前半段扫一遍,累计答案即可,时间复杂度,n*lgn*lga

技术分享
 1 # include <cstdio>
 2 # include <cstring>
 3 # include <cstdlib>
 4 # include <iostream>
 5 # include <vector>
 6 # include <queue>
 7 # include <stack>
 8 # include <map>
 9 # include <bitset>
10 # include <sstream>
11 # include <set>
12 # include <cmath>
13 # include <algorithm>
14 using namespace std;
15 # define LL          long long
16 # define pr          pair
17 # define mkp         make_pair
18 # define lowbit(x)   ((x)&(-x))
19 # define PI          acos(-1.0)
20 # define INF         0x3f3f3f3f3f3f3f3f
21 # define eps         1e-8
22 # define MOD         1000000007
23 
24 inline int scan() {
25     int x=0,f=1; char ch=getchar();
26     while(ch<0||ch>9){if(ch==-) f=-1; ch=getchar();}
27     while(ch>=0&&ch<=9){x=x*10+ch-0; ch=getchar();}
28     return x*f;
29 }
30 inline void Out(int a) {
31     if(a<0) {putchar(-); a=-a;}
32     if(a>=10) Out(a/10);
33     putchar(a%10+0);
34 }
35 # define MX 100005
36 /**************************/
37 
38 int n;
39 LL ans;
40 int num[MX];
41 int AND[MX];
42 int OR[MX];
43 int tot[MX];
44 
45 void dfs(int l,int r)
46 {
47     if (l==r)
48     {
49         ans = (ans+(LL)num[l]*num[r]%MOD)%MOD;
50         return;
51     }
52     int mid = (l+r+1)>>1;
53     int pos = mid;
54     tot[pos]=0; AND[pos]=OR[pos]=num[pos];
55     for (int i=mid;i<=r;i++)
56     {
57         if ( (num[i]&AND[pos]) != AND[pos] || (num[i]|OR[pos]) != OR[pos] )
58         {
59             pos++;
60             AND[pos] = (num[i]&AND[pos-1]);
61             OR[pos] = (num[i]|OR[pos-1]);
62             tot[pos]=1;
63         }
64         else tot[pos]++;
65     }
66     int tpA = num[mid-1];
67     int tpO = num[mid-1];
68     for (int i=mid-1;i>=l;i--)
69     {
70         tpA&=num[i], tpO|=num[i];
71         for (int j=mid;j<=pos;j++)
72             ans = (ans + ((LL)(tpA&AND[j])*(tpO|OR[j])%MOD) *tot[j]%MOD)%MOD;
73     }
74     dfs(mid,r);
75     dfs(l,mid-1);
76 }
77 
78 int main()
79 {
80     scanf("%d",&n);
81     for (int i=1;i<=n;i++)
82         num[i]=scan();
83     ans = 0;
84     dfs(1,n);
85     printf("%I64d\n",ans);
86     return 0;
87 }
View Code

 

 

 

1674 区间的价值 V2(分治)

标签:不同   family   return   fine   show   div   define   closed   alt   

原文地址:http://www.cnblogs.com/haoabcd2010/p/7522764.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!