码迷,mamicode.com
首页 > 编程语言 > 详细

【题解】子数组有主元素

时间:2019-04-05 16:47:36      阅读:194      评论:0      收藏:0      [点我收藏+]

标签:多少   names   main   fine   输入数据   can   ring   name   def   

题目描述

  一个数组B,如果有其中一个元素出现的次数大于length(B) div 2,那么该元素就是数组B的主元素,显然数组B最多只有1个主元素,因为数组B有主元素,所以被称为“优美的”。

  给出数组A[0..n-1],问数组A有多少个“优美的”子数组。数组A的子数组是由数组A的连续若干个元素构成的数组。数组A不是直接给出的,而是通过如下公式自动产生的:

for i = 0 to n-1 do

{

  A[i] = (seed div 2^16) % m

  seed = (seed * 1103515245 + 12345) % 2^31

}

  如上公式中:  n, seed, m都是输入数据给出的,div是表示整数的整除。^是表示幂运算。

 

输入输出格式

输入格式

  一行,3个整数,n,  seed,  m。1 <= n <= 100000。 0 <= seed <= 2^31-1。 1 <= m <= 50。

 

输出格式

  一个整数。

 

输入输出样例

输入样例一

5  200  5

 

输出样例一

8

 

输入样例二

10  15  3

 

输出样例二

23

 

输入样例三

8  12345678  1

 

输出样例三

36

 

输入样例四

27  541  50

 

输出样例四

27 

 

题解

  观察此题,$m$很小,我们可以从这里入手。

  枚举$[0,m]$中的$i$,设$d[j]$为$[1,j]$中$a$数组内元素$i$的数量,$d[0]=0$,那么很容易想到,如果$[l,r]$有主元素,那么$d[r]-d[l-1]>0$即$d[r]>d[l-1]$。

  此时我们可以设$s[k]$为$[1,j]$中$d$数组内元素$k$的数量,用树状数组等维护一下即可,这样就可以用$O(mnlogn)$的时间复杂度通过这题了。

技术图片
#include <iostream>
#include <cstdio>
#include <cstring>

#define MAX_N (100000 + 5)

#define lowbit(x) ((x) & -(x))

using namespace std;

int n;
int a[MAX_N];

int seed, m;
const int pow2_16 = 1 << 16;
const long long pow2_32 = 1ll << 31;

int d[MAX_N];
int s[MAX_N + MAX_N];
long long ans;

int main()
{
    scanf("%d%d%d", &n, &seed, &m);
    for(register int i = 1; i <= n; ++i)
    {
        a[i] = (seed / pow2_16) % m;
        seed = (seed * 1103515245ll + 12345) % pow2_32;
    }
    for(register int i = 0; i < m; ++i)
    {
        d[0] = 0;
        memset(s, 0, sizeof s);
        for(register int j = n + 1; j <= n + n + 1; j += lowbit(j))
        {
            ++s[j];
        }
        for(register int j = 1; j <= n; ++j)
        {
            if(a[j] == i) d[j] = d[j - 1] + 1;
            else d[j] = d[j - 1] - 1; 
            for(register int k = d[j] + n; k; k -= lowbit(k))
            {
                ans += s[k];
            }
            for(register int k = d[j] + n + 1; k <= n + n + 1; k += lowbit(k))
            {
                ++s[k];
            }
        }
    }
    printf("%lld", ans);
    return 0;
}
参考程序O(mnlogn)

 

【题解】子数组有主元素

标签:多少   names   main   fine   输入数据   can   ring   name   def   

原文地址:https://www.cnblogs.com/kcn999/p/10659046.html

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