HDU 6319

题意略。

思路:倒着使用单调队列,大的放在前,小的放在后。

详见代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL maxn = 1e7 + 5;

LL a[maxn];
int n,m,k;
LL p,q,r,mod;
int que[maxn],head,tail;
LL ans[maxn];

LL generator(int i){
    return ((p * a[i - 1]) % mod + q * i % mod + r) % mod;
}

int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        head = tail = 0;
        scanf("%d%d%d%lld%lld%lld%lld",&n,&m,&k,&p,&q,&r,&mod);
        for(int i = 1;i <= k;++i) scanf("%lld",&a[i]);
        for(int i = k + 1;i <= n;++i) a[i] = generator(i);
        for(int i = n;i >= n - m + 1;--i){
            while(head < tail && a[que[tail - 1]] <= a[i]) --tail;
            que[tail++] = i;
        }
        LL A = 0,B = 0;
        A += a[que[head]] ^ (n - m + 1);
        B += (tail - head) ^ (n - m + 1);
        //printf("%d
",tail - head);
        for(int i = n - m;i >= 1;--i){
            while(que[head] > i + m - 1 && head < tail) ++head;
            while(head < tail && a[que[tail - 1]] <= a[i]) --tail;
            que[tail++] = i;
            A += a[que[head]] ^ i;
            B += (tail - head) ^ i;
        //    printf("%d
",tail - head);
        }
        printf("%lld %lld
",A,B);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/tiberius/p/9392638.html