zoukankan      html  css  js  c++  java
  • Ascending Rating(单调队列)

    题目传送门Ascending Rating:

    给定一个序列(a[1...n]),对于每个长度为(m)的连续子区间,求出区间的最大值以及从左往右扫描该区间时最大值的变化次数。

    考虑到输出可能很大,分别求出异或和即可.

    一个长度为n的序列,给出序列的前k个值,剩下的([k+1,n])可以由题目给出的公式推出.

    把每个长度为m的区间看作滑动窗口,其实本题就是滑动窗口的升级版.

    while(T--){
    	ans1=ans2=0;
    	n=read();m=read();k=read();
        p=read();q=read();r=read();mod=read();
    //p,q,r,mod仅用于推出剩下的序列
    	for(int i=1;i<=k;i++)a[i]=read();
    //给出序列的前k个值
    	for(int i=k+1;i<=n;i++)
        	a[i]=(1LL*p*a[i-1]+1LL*q*i+r)%mod;
    //由题目给出的公式推出剩下的序列
    	int l=1,r=0;
    	for(int i=n;i>=1;i--){//从后往前扫描
    	    while(l<=r&&a[Q[r]]<=a[i])r--;
    //队列Q中记录的是元素的编号(1~n),而不是元素的值
    //构建单调递减的队列
    	    Q[++r]=i;
    //将这个元素入队
    	    if(i+m-1<=n){//小区间m全部在序列n中
    			while(Q[l]>=i+m)l++;
    //把"过期"的元素踢出队列
    			ans1+=i^a[Q[l]];
    			ans2+=i^(r-l+1);
    //因为我们构建的是单调递减队列,所以队头元素是最大值.
    //又因为是从后往前扫描,相当于从前往后的单调递增队列
    //所以队列长度就是最大值更新的次数
    	    }
    	}
    	printf("%lld %lld",ans1,ans2);
    	printf("
    ");
    }
    
  • 相关阅读:
    Java String, StringBuffer和StringBuilder实例
    java中字符串的比较
    java中子类继承父类时是否继承构造函数
    Java中抽象类和接口的用法和区别
    与(&)、非(~)、或(|)、异或(^)
    Linux03
    Linux02
    Linux01
    力扣算法题
    算法 栈、队列、二分查找
  • 原文地址:https://www.cnblogs.com/PPXppx/p/10321990.html
Copyright © 2011-2022 走看看