Problem A. Ascending Rating [单调队列维护区间最大值/最大值更新次数]

Problem A. Ascending Rating 

题意: 给一个序列,求长为m的n-m+1个区间的最大值和最大值更新次数

思路: 单调队列维护长为m的区间最大值没问题... 至于后面的最大值更新次数,把序列倒过来,再从前往后扫,对应的队列中的size,就是长为m的区间中,从第一个数开始单调上升序列的长度了

单调队列除了能维护区间最大值之外,还能维护从第i个作为起点,到第i+m-1区间的 最大值更迭次数

#include<cstdio>
#include<vector>
#include<cmath>
#include<string>
#include<queue>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<map>
#define PI acos(-1.0)
#define pb push_back
#define F first
#define S second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1e7+7;
//const int MOD=1e9+7;
template <class T>
bool sf(T &ret){ //Faster Input
    char c; int sgn; T bit=0.1;
    if(c=getchar(),c==EOF) return 0;
    while(c!='-'&&c!='.'&&(c<'0'||c>'9')) c=getchar();
    sgn=(c=='-')?-1:1;
    ret=(c=='-')?0:(c-'0');
    while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
    if(c==' '||c=='\n'){ ret*=sgn; return 1; }
    while(c=getchar(),c>='0'&&c<='9') ret+=(c-'0')*bit,bit/=10;
    ret*=sgn;
    return 1;
}
int n,m,p,q,k,r,mod;
int a[N];
void mian(){
    sf(n),sf(m),sf(k);sf(p);
    sf(q),sf(r),sf(mod);

    for(int i=1;i<=k;i++)   sf(a[i]);
    for(int i=k+1;i<=n;i++) a[i]=(1ll*p*a[i-1]+1ll*q*i+r)%mod;
    deque<pair<int,int> > q;
    reverse(a+1,a+1+n);
//    for(int i=1;i<=n;i++)   cout << a[i]<<" ";
//    cout << endl;
    ll A=0,B=0;
    int jj=n-m+1;
    for(int i=1,j=1;i<=n-m+1;i++){
        while(j<=i+m-1){
            while(!q.empty() && a[j]>=q.back().F) q.pop_back();
            q.push_back({a[j],j++});
        }
        while(q.front().S< i) q.pop_front();
        A=A+(q.front().F ^ jj);
        if(q.front().F!=0)  B=B+((int)q.size() ^ jj);
//        cout << q.front().F<< "^" <<jj<<endl;
//        cout << q.size()<< "^" <<jj<<endl;
//        cout <<"-----------"<<endl;
        jj--;
    }
    printf("%lld %lld\n",A,B);
}

int main(void){
    int T;
    sf(T);
    while(T--){
        mian();
    }

    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值