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("
    ");
    }
    
  • 相关阅读:
    添加可运行的js代码
    一,IL访问静态属性和字段
    UI基础UIWindow、UIView
    ASP.NET MVC:会导致锁定的会话
    2013腾讯编程马拉松初赛
    使用phantomjs生成网站快照
    C语言
    设置 Ext.data.Store 传参的请求方式
    HDU 2041 超级楼梯
    MySQL 监控-innotop
  • 原文地址:https://www.cnblogs.com/PPXppx/p/10321990.html
Copyright © 2011-2022 走看看