zoukankan      html  css  js  c++  java
  • HDU 6319.Problem A. Ascending Rating-经典滑窗问题求最大值以及COUNT-单调队列 (2018 Multi-University Training Contest 3 1001)

    2018 Multi-University Training Contest 3

    6319.Problem A. Ascending Rating

    题意就是给你长度为k的数列,如果数列长度k<n,就利用一个构造数列的方法构造数列使数列长度为n。

    然后求定长区间为m的数列中最大值是几,最大值是第几次更新maxnum得到的,得到所有结果之后,用一个求和的公式将结果输出来,具体题意自己翻译。

    滑窗问题,单调队列可以解决。关于滑窗问题和单调队列,具体的自行百度。

    对于这个题,倒着遍历数列才能既找到最大值,又能找到COUNT,如果正着遍历,只能找到最大值,但是没法用tail-head得到COUNT,可能标记进来过的数的下标然后区间求和应该也可以得到,但是超不超时就不知道了。。。

    官方题解:

    按照r从m到n的顺序很难解决这个问题。

    考虑按照r从n到m的顺序倒着求出每个区间的答案。按照滑窗最大值的经典方法维护a的单调队列,那么队列中的元素个数就是最大值的变化次数。

    时间复杂度O(n)

    其他的应该没什么了。

    代码:

     1 //1001-经典滑窗问题-单调队列
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<cstdlib>
     6 #include<queue>
     7 #include<algorithm>
     8 #include<cassert>
     9 #include<queue>
    10 #include<set>
    11 using namespace std;
    12 typedef long long ll;
    13 const int maxn=1e7+10;
    14 
    15 int arr[maxn],maxval[maxn],que[maxn],num[maxn];
    16 int n,m,k,p,q,r,mod;
    17 
    18 void getAns(int n,int m)
    19 {
    20     int head=0,tail=0;
    21     for(int i=n;i>=1;i--){
    22         while(tail>head&&arr[que[tail-1]]<=arr[i]) tail--;
    23         que[tail++]=i;
    24         if(i>n-m+1) continue;
    25         while(que[head]>i+m-1) head++;//队头距离当前区间太远,head++变大,才满足区间长度,因为head越大,就越接近tail,因为是倒着的
    26         maxval[i]=arr[que[head]];
    27         num[i]=tail-head;//对每个区间的count为队尾-队头的值
    28     }
    29 }
    30 
    31 int main()
    32 {
    33     int t;
    34     scanf("%d",&t);
    35     while(t--){
    36         scanf("%d%d%d%d%d%d%d",&n,&m,&k,&p,&q,&r,&mod);
    37         for(int i=1;i<=k;i++)
    38             scanf("%d",&arr[i]);
    39         for(int i=k+1;i<=n;i++)
    40             arr[i]=((ll)p*arr[i-1]%mod+(ll)q*i%mod+r)%mod;
    41         getAns(n,m);
    42         ll a=0,b=0;
    43         for(int i=1;i<=n-m+1;i++){
    44             a+=maxval[i]^i;
    45             b+=num[i]^i;
    46         }
    47         printf("%lld %lld
    ",a,b);
    48     }
    49 }

    mdzz,求数列的时候,取模写错了,wa了好几次。

  • 相关阅读:
    shell得到两个文件的差集
    shell 单引号&双引号的使用
    kubernetes session and 容器root权限
    docker 使用网络以及容器互联
    倒计时练习
    会话控制
    XML
    AJAX实现搜索智能提示
    弹窗显示详情练习
    三级联动
  • 原文地址:https://www.cnblogs.com/ZERO-/p/9409967.html
Copyright © 2011-2022 走看看