标签:多少 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; }
标签:多少 names main fine 输入数据 can ring name def
原文地址:https://www.cnblogs.com/kcn999/p/10659046.html