zoukankan      html  css  js  c++  java
  • HDU 6319 Problem A. Ascending Rating(单调队列)

    要求一个区间内的最大值和每次数过去最大值更新的次数,然后求每次的这个值异或 i 的总和。

    这个序列一共有n个数,前k个直接给出来,从k+1到n个数用公式计算出来。

    因为要最大值,所以就要用到单调队列,然后从后往前扫一遍然后每次维护递减的单调队列。

    先把从n-m+1以后开始的数放进单调队列,这时候先不操作,然后剩下的数就是要异或相加的数,然后每次的队首元素就是这个区间内的最大值,这个队列里的元素个数,其实就是更新到最大值的逆过程,也就是最大值需要更新的次数。

    #include<map>
    #include<set>
    #include<ctime>
    #include<cmath>
    #include<stack>
    #include<queue>
    #include<string>
    #include<vector>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define lowbit(x) (x & (-x))
    
    typedef unsigned long long int ull;
    typedef long long int ll;
    const double pi = 4.0*atan(1.0);
    const int inf = 0x3f3f3f3f;
    const int maxn = 10000100;
    const int maxm = 1000005;
    using namespace std;
    
    int T, tol;
    int n, m;
    ll a[maxn];
    int que[maxn];
    
    void init() {
        memset(a, 0, sizeof a);
    }
    
    int main() {
        scanf("%d", &T);
        while(T--) {
            int k;
            int p, q, r, mod;
            scanf("%d%d%d%d%d%d%d", &n, &m, &k, &p, &q, &r, &mod);
            for(int i=1; i<=k; i++)    scanf("%lld", &a[i]);
            for(int i=k+1; i<=n; i++)    a[i] = (1ll*p*a[i-1] + 1ll*q*i + r) % mod;
            int head, tail;
            head = tail = 0;
            for(int i=n; i>n-m+1; i--) {
                while(head != tail && a[i] >= a[que[tail-1]])    tail--;
                que[tail++] = i;
            }
            /*
            for(int j=head; j<tail; j++)    printf("%d %d %lld
    ", i, que[j], a[que[j]]);
            printf("
    ");
            */
            ll ans1 = 0;
            ll ans2 = 0;
            for(int i=n-m+1; i>=1; i--) {
                while(head != tail && a[i] >= a[que[tail-1]])    tail--;
                que[tail++] = i;
                while(i + m - 1 < que[head])    head++;
                /*
                for(int j=head; j<tail; j++)    printf("%d %d %lld
    ", i, que[j], a[que[j]]);
                printf("
    ");
                */
                ans1 += (a[que[head]] ^ i);
                ans2 += ((tail - head) ^ i);
            }
            printf("%lld %lld
    ", ans1, ans2);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    9月7日总结
    Arbitrage题解
    杀蚂蚁题解
    8月11日总结
    8月10总结
    PHP 关于获取客户端ip的方法
    PHP内置函数大全
    PHP header函数设置http头
    获取两个日期之间的全部的日期数据(包括两个日期)
    根据周日获取这周的周日到周六的日期(周日为这周的第一天)
  • 原文地址:https://www.cnblogs.com/Jiaaaaaaaqi/p/9395239.html
Copyright © 2011-2022 走看看