A - Problem A. Ascending Rating
题意:给出n个数,给出区间长度m。对于每个区间,初始值的max为0,cnt为0.遇到一个a[i] > ans, 更新ans并且cnt++。计算
$A = \sum_{i = 1}^{i = n - m +1} (max \oplus i)$
$B = \sum_{i = 1}^{i = n - m +1} (cnt \oplus i)$
思路:单调队列,倒着扫一遍,对于每个区间的cnt就是队列的长度,扫一遍即可。
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 const int maxn = 1e7 + 10; 6 typedef long long ll; 7 8 int t; 9 int n,m,k; 10 ll p, q, r, mod; 11 ll arr[maxn]; 12 ll brr[maxn]; 13 14 int main() 15 { 16 scanf("%d", &t); 17 while(t--) 18 { 19 scanf("%d %d %d %lld %lld %lld %lld", &n, &m, &k, &p, &q, &r, &mod); 20 for(int i = 1; i <= n; ++i) 21 { 22 if(i <= k) scanf("%lld", arr + i); 23 else arr[i] = (p * arr[i - 1] + q * i + r) % mod; 24 } 25 ll A = 0, B = 0; 26 int head = 0, tail = -1; 27 for(int i = n; i > (n - m + 1); --i) 28 { 29 while(head <= tail && arr[i] >= arr[brr[tail]]) tail--; 30 brr[++tail] = i; 31 } 32 for(int i = n - m + 1; i >= 1; --i) 33 { 34 while(head <= tail && arr[i] >= arr[brr[tail]]) tail--; 35 brr[++tail] = i; 36 while(brr[head] - i >= m) head++; 37 A += arr[brr[head]] ^ i; 38 B += (tail - head + 1) ^ i; 39 } 40 printf("%lld %lld\n", A, B); 41 } 42 return 0; 43 }