Problem A. Ascending Rating HDU - 6319

题意:给出一个长度为n的序列(a1, a2, a3, …… an),询问A=∑(maxratingi⊕i), B=∑(counti⊕i)(i = 1, 2, … n - m + 1), 其中maxrating为(ai, ai + 1, ….. , a i + m - 1)的最大值, count为(ai, ai + 1, ….. , a i + m - 1)从ai开始严格递增的序列的长度。数组a并不会全部给出,给出前k个,后面的数组由公式:ai=(p×ai−1+q×i+r)modMOD推出


题解:从后向前维护一个单调递减的队列每次取最后一个为最大值,队列的大小为count计算即可


AC代码:

#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = a; i <= b; i++)
#define per(i, a, b) for(int i = a; i >= b; i--)
#define met(a, b) memset(a, b, sizeof(a))
typedef long long ll;
const int maxn = 1e7 + 10;
ll n, m, k, p, qq, r, mod, T;
ll a[maxn];
const ll inf = 0x3f3f3f3f;
inline ll read()
{
    ll x=0LL,f=1LL;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10LL+ch-'0';ch=getchar();}
    return x*f;
}
int main() {
    T = read();
    while(T--) {
        n = read();
        m = read();
        k = read();
        p = read();
        qq = read();
        r = read();
        mod = read();
        for(int i = 1; i <= k; i++) a[i] = read();
        for(int i = k + 1; i <= n; i++) a[i] = (ll)((ll)p * a[i - 1] + (ll)qq * (ll)i + (ll)r) % mod;
        deque<ll> q;
        q.clear();
        ll now = inf;
        ll posl = n, posr = n, A = 0, B = 0;
        for(posl; posl >= 1; posl--) {
            while(!q.empty() && a[posl] >= q.front()) q.pop_front();
            q.push_front(a[posl]);
            if(posr - posl + 1 == m) {
                A += q.back() ^ posl;
                B += q.size() ^ posl;
                if(q.back() == a[posr]) q.pop_back();
                posr--;
            }
        }
        printf("%lld %lld\n", A, B);
    }
    return 0;
}
//1201
//100 13 100 5 5 5 5
//180494088 158873714 479877681 657558775 416667558 741795717 739981730 493259342 796614024 602026990 606180151 680655616 674824307 799901869 302810848 497452923 871034045 999301444 12976297 663914202 565761338 573768359 40362688 545018995 801799468 715498110 86592465 864571874 973075533 487083863 300857180 84397243 426674756 478342417 385309993 182423654 702297761 6037161 744871574 921238503 840011306 36346558 372830293 818350693 315959279 418289659 38586932 465431988 984633105 81117525 566090197 789414313 900383332 540555441 771759031 534410997 82276291 709236428 676653888 430935770 411255646 566949886 71999553 54529779 712275805 104626488 865842580 463594979 807007188 510218879 684267757 449641115 117372131 359309070 390323387 962489343 338751285 843070467 829791137 890460312 670196706 185144316 580321035 414078214 75520301 404086258 178090269 73183911 34001050 618921657 827906597 351414875 269110270 450711890 404144789 64678126 798888336 841998513 50728697 529743089
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值