2018多校3Problem A. Ascending Rating

7 篇文章 0 订阅

HDOJ6319

 

主要看注释(感觉发布格式环境不太顺手)

/*
2018年8月7日15:30:53终于读懂了这段短小精悍的代码,开始反思和复盘,以及思考自己怎么才能写出这么牛逼的代码
2018年8月7日16:06:08去CSDN分享记录一下,万一帮到别人呢
*/
#include<cstdio>
const int N=10000010;
int T,n,m,k,P,Q,R,MOD,i,a[N],q[N],h,t;long long A,B;
int main(){
  scanf("%d",&T);
  while(T--){
    scanf("%d%d%d%d%d%d%d",&n,&m,&k,&P,&Q,&R,&MOD);
    for(i=1;i<=k;i++)scanf("%d",&a[i]);
    for(i=k+1;i<=n;i++)a[i]=(1LL*P*a[i-1]+1LL*Q*i+R)%MOD;//1ll将int转化为long long
    for(h=1,t=A=B=0,i=n;i;i--){//while(n--)的加局部的初始条件的版本
    //设计地太精妙,以致我慢慢推他的步骤都有点看不懂,额,我太菜了,去看看百度有没有更详细的解题思路讲解
      while(h<=t&&a[q[t]]<=a[i])t--;//这里的while() t--,是确保维护的逆序单调递减队列里面t的值确实等于count改变次数
      //有区间控制阀门h<=t
      q[++t]=i;//t记录了逆序全过程中所有count+1的次数,而q[t]则正好是当时的位置(这里的代码看了超级久)
      if(i+m-1<=n){//从有向左移动了一个区间的时候
        while(q[h]>=i+m)h++;//序号过界了,得扯回来(符合一个区间的大小数),所以q[h]是单增序列的最后一个数的下标
        //而且这里h和t同级,控制序号数组q[]
        A+=i^a[q[h]];//控制的逆序递减序列中,a[q[h]]一定是最大的那个
        B+=i^(t-h+1);//从右往左那这里的count一开始是1,和从左往右情况不一定相同,这怎么会对?
        //苦恼了半天后面发现题目中没有说小Q教练是严格地安照从左往右数,而是随便找区间
        //然后B的求解方程虽然说是安照i=1到n-m+1,但是并没有说count(i)是怎么来的

        //上面自己写的一些也是猜的较多,去支持自己的观点,后面自己又读了好多次题目,
        //惊呆地发现了我确实又又又读错了,原来是小Q教练在每个区间里面从左往右(每个区间count都是从0开始的!!!)
      }
    }//在外面找的代码和这个是一样的,还是看这个吧,一个个地慢慢推先
    printf("%lld %lld\n",A,B);
  }
}

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值