zoukankan      html  css  js  c++  java
  • 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
    ",ans);
    86     return 0;
    87 }
    View Code

     

     

  • 相关阅读:
    个人项目(Word Count Java)
    自我介绍+软工5问
    第六次实践
    第五次实践作业
    第四次实践作业
    第三次实践作业
    第二次实践作业
    第1次实践作业
    第06组 Beta版本演示
    第06组 Beta冲刺(4/4)
  • 原文地址:https://www.cnblogs.com/haoabcd2010/p/7522764.html
Copyright © 2011-2022 走看看