51nod 1589 移数博弈【桶排序+链表】

1589 移数博弈 

基准时间限制:1 秒 空间限制:262144 KB 分值: 80 难度:5级算法题
 

小A和小B在玩一个游戏。

他们拥有一个数列。

小A在该数列中选择出最大的那个数,然后移出该数列。

小B在剩下的数列中选择出最大的那个数,并乘上小A的那个值,作为他的答案。

那么现在问题来了。

他们现在想换一种玩法,把该数列长度大于等于2的区间(即n*(n-1)/2个区间)单独作为一个数列拿出来,然后做一次上述的游戏,然后计算出小B所有的答案,考虑到输出那么多数比较困难,因此他们想知道所有答案和对 1e9+7取模后的值。

 

样例解释:

该数列为2,0,1,2

对于1-2的区间答案为0

对于1-3的区间答案为2

对于1-4的区间答案为4

对于2-3的区间答案为0

对于2-4的区间答案为2

对于3-4的区间答案为2



Input
第一行五个数n,a0,a,b,p(1<=n,a0,a,b,p<=10000000)。
该数列的构造方法为,a[i]=(a[i-1]*a+b)%p。该数列的下标为1~n。
Output
1行,表示答案。
Input示例
4 1 1 1 3
Output示例
10

题解:

  设当前为now

  设now之前第一个比他大的数的位置为L1,L1之前第一个比他大的数的位置为L2 

  设now之后第一个比他大的数的位置为R1,R1之后第一个比他大的数的位置为R2 

  那么对于now,其作为次大值存在的区间有:

    1、左端点在[L2+1,L1]之间,右端点在[now,R1-1]之间 

    2、左端点在[L1+1,now]之间,右端点在[R1,R2-1]之间。

  因为此题数据范围n在1~1e7,最大值p范围在1~1e7,所以考虑用桶排序优化合适。

  然后维护一个链表,从小到大枚举数,枚举完就删除,保证每次枚举的数是链表中最小的。这样就可以控制复杂度在O(N)啦。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e7+5;
const int MOD = 1e9+7;
int a[N], b[N];//b[i]=j 表示a[j]排序后在i位置
int vis[N];
int pre[N], nex[N];
void del(int now) {//删除now节点
    nex[pre[now]] = nex[now];
    pre[nex[now]] = pre[now];
}
int main() {
    int n, aa, bb, p, i, j;
    ll ans = 0;
    scanf("%d%d%d%d%d", &n, &a[0], &aa, &bb, &p);
    for(i = 1; i <= n; ++i) a[i] = (1ll * a[i-1] * aa + bb) % p;
    //桶排序
    for(i = 1; i <= n; ++i) vis[a[i]]++;
    for(i = 1; i < p; ++i) vis[i] += vis[i-1];
    for(i = n; i >= 1; --i) b[vis[a[i]]--] = i;
    //链表
    pre[0] = 0; nex[n+1] = n+1;
    for(i = 1; i <= n; ++i) {
        pre[i] = i - 1;
        nex[i] = i + 1;
    }
    for(i = 1; i <= n; ++i) {
        int now = b[i];
        int l1 = pre[now];
        int l2 = pre[l1];
        int r1 = nex[now];
        int r2 = nex[r1];
        ans = (ans + (1ll*a[now]*a[l1]%MOD*(l1-l2)%MOD*(r1-now)%MOD)) % MOD;
        ans = (ans + (1ll*a[now]*a[r1]%MOD*(now-l1)%MOD*(r2-r1)%MOD)) % MOD;
        del(now);
    }
    printf("%lld\n", ans);
    return 0;
}

 

 

posted @ 2018-04-12 23:40  GraceSkyer  阅读(443)  评论(0编辑  收藏  举报

~~~~~~ACM大牛语录,激励一下~~~~~~

为了世界的和平,为了女生的安全,我拼命做题,做题,做题!

用最短的时间,刷最多的题!

给我一滴泪,我就看到了你全部的海洋!

seize the hour, seize the day.

人生难免有无奈,幸福走远了,或是感叹幸福来迟了.其实我一直相信,无论手中的幸福是多么微不足道的感觉,我会把握住那每一分,每一秒,当幸福依旧像那百鸟般飞逝,终究无法掌握时,我会感谢它,曾经降临过!

A自己的题,让别人郁闷去吧

WA肠中过,AC心中留 TLE耳边过,AC特别牛

天然的悲苦和伤逝,过去有过,以后还会有

^*^一步一步往上爬^*^

AC就像练级,比赛就像PK. 练级不如PK好玩

其实,世上本没有ACM,AC的人多了,也便有了!

AC无止尽~ Seek you forever~

找呀找呀找水题,找到一个AC一个呀!

AC是检验程序的唯一标准。

真的猛士,敢于直面惨淡的人生,敢于正视淋漓的鲜血……