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了好几次。

  • 相关阅读:
    228. Summary Ranges
    227. Basic Calculator II
    224. Basic Calculator
    222. Count Complete Tree Nodes
    223. Rectangle Area
    221. Maximal Square
    220. Contains Duplicate III
    219. Contains Duplicate II
    217. Contains Duplicate
    Java编程思想 4th 第4章 控制执行流程
  • 原文地址:https://www.cnblogs.com/ZERO-/p/9409967.html
Copyright © 2011-2022 走看看