1674 区间的价值 V2(分治)

Posted happy_code

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1674 区间的价值 V2(分治)相关的知识,希望对你有一定的参考价值。

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(分治)的主要内容,如果未能解决你的问题,请参考以下文章

[hdu] 5696 区间的价值 || 序列分治

HDU5696 区间的价值

ACM学习历程—HDU5696 区间的价值(分治 && RMQ && 线段树 && 动态规划)

Foreign动态规划 [分治][DP]

1564 区间的价值

51nod1164 最高的奖励 V2