zoukankan      html  css  js  c++  java
  • 北邮校赛 F. Gabriel's Pocket Money(树状数组)

    时间限制 2000 ms 内存限制 65536 KB

    题目描述


    For centuries, Heaven has required its young angels to live and study among humans in order to become full-fledged angels. This is no different for top-of-her-class Gabriel White Tenma, who believes it is her mission to be a great angel who will bring happiness to mankind.
    However, Gabriel grows addicted to video games on Earth and eventually becomes a hikikomori. What's worse, her grades in school becomes erratic, which directly determines how much pocket money she could get from Heaven. Every week Gabriel needs to report her recent grade in school, and Heaven will give her some money based on her reports. In each report Gabriel is asked to offer two grades, the grade she get this week and a grade she has ever got before this week to show she is improved or at least not going backwards, like "I once got 59 points, and I get 61 points this week. So I'm improved!" or "I once got 59 points, and this week I get 59 points again. So I'm not going backwards!". Then Heaven will give her as much pocket money as her former grade points she reported (In both cases, she can get 59 dollars. What a hardworking angel!). If she can't offer such report, no pocket money would be offered this week. For example, the first week (she has only one grade).
    Gabriel knows how to maximize the pocket money she get from heaven. Giving you Gabriel's transcript of this semester in order, can you figure out how much pocket money she can get in total?

    输入格式

    Input contains multiple test cases.
    For each test case:

    • The first line contains an integers n(1n106), indicating the number of weeks;
    • The second line contains n integers a1,a2,...,an(0ai106).

    输出格式

    For each test case, output a number in a single line, indicating the total pocket money Gabriel can get. You should let answer modulo 19260817 before printing it.

    输入样例

    3
    1 2 3
    5
    3 5 1 2 4
    

    输出样例

    3
    7
    【题意】给你一个数组,然后对于每个数,找到左边小于等于它的最大的那个数,然后依次累加起来。
    【分析】数据小的话,可以O(N*N)来做,可是 N<1e6,那就只能树状数组了,对于每一个数,向上lowbit更新Lazy标记,Lazy标记的是
    到目前为止这个数左边小于等于它的最大的数,那么查询的时候只需要向下lowbit查询取最大值就行了,复杂度NlogN。
    #include <bits/stdc++.h>
    #define mp make_pair
    #define pb push_back
    #define met(a,b) memset(a,b,sizeof a)
    #define inf 10000000
    using namespace std;
    typedef long long ll;
    typedef pair<int,int>pii;
    const int N = 1e6+5;
    const double eps = 1e-8;
    int n,sum[N],m,cnt,k;
    int lazy[N],a[N];
    void update(int x,int num){
        for(int i=x;i<N;i+=i&(-i)){
            lazy[i]=max(lazy[i],num);
        }
    }
    int query(int x){
        int ret=0;
        for(int i=x;i>=1;i-=i&(-i)){
            ret=max(ret,lazy[i]);
        }
        return ret==0?ret:ret-1;
    }
    int main() {
        int T,x,y,xx,yy;
        while(~scanf("%d",&n)){
            met(lazy,0);
            for(int i=1;i<=n;i++){
                scanf("%d",&a[i]);
                a[i]++;
            }
            ll ans=0;
            for(int i=1;i<=n;i++){
                int s=query(a[i]);
                ans=(ans+s)%19260817;
                update(a[i],a[i]);
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    ADO.Net对Oracle数据库的操作(转)
    代码反思(1)
    继承与多态
    存储过程
    linux学习流程及内容概括
    Linux下终端快捷键
    查找算法
    epoll解读
    TCP/udp编程
    如何学习嵌入式
  • 原文地址:https://www.cnblogs.com/jianrenfang/p/6788992.html
Copyright © 2011-2022 走看看