zoukankan      html  css  js  c++  java
  • Tallest Cow

    Tallest Cow

    有一个长度为n的正整数序列({a_i}),现在给出其中最大的数字为h,并给出R组关系,第i组关系用二元组((l_i,r_i))表示,表示(a_{l_i+1}sim {r_i-1})间的数字都要比(a_{l_i},a_{r_i})小,询问对于每个i,(a_i)的最大值。

    不妨设一个序列({b_i}),初始全部为0,对于每一组关系,如((l_i,r_i)),那么就把(b_{l_i+1}sim b_{r_i-1})全部减1,显然这样是(O(n^2)),考虑优化,容易知道这是区间的维护,除了考虑写难写的线段树和分块外,区间问题还有一个著名的思想,就是将区间的信息保存在两个端点上,通过前缀和体现信息,不妨设一个序列({c_i}),初始化为0,对于关系((l_i,r_i))而言,就(--c_{l_i+1},++c_{r_i}),这样维护出来的序列c的前缀和({s_i}),易知(s_i=b_i),于是问题得到解决。

    最后因为关系会重复输入,于是我们还要hash判重,但是我们还是可以最后做到(O(n))

    参考代码:

    #include <iostream>
    #include <cstdio>
    #define il inline
    #define ri register
    #define key 156511
    #define swap(x,y) x^=y^=x^=y
    using namespace std;
    struct data{
        data*next;int j,k;
    }*head[key],*pt;
    int A[10001];
    il bool exist(int,int);
    il void insert(int,int);
    int main(){
        int n,s,h,r;
        scanf("%d%d%d%d",&n,&s,&h,&r);
        for(int i(1),j,k;i<=r;++i){
            scanf("%d%d",&j,&k);if(j>k)swap(j,k);
            if(exist(j,k))--A[j+1],++A[k],insert(j,k);
        }
        for(int i(1);i<=n;++i)A[i]+=A[i-1],printf("%d
    ",A[i]+h);
        return 0;
    }
    il bool exist(int j,int k){
        int H((j+k*10001)%key);
        for(pt=head[H];pt!=NULL;pt=pt->next)
            if(pt->j==j&&pt->k==k)return false;
        return true;
    }
    il void insert(int j,int k){
        int H((j+k*10001)%key);
        pt=new data,pt->j=j,pt->k=k,
            pt->next=head[H],head[H]=pt;
    }
    
    
  • 相关阅读:
    Python 队列
    Python 栈
    Python面试百题
    TCP:四次挥手
    TCP:三次握手
    SQL:八 SQL高级处理
    SQL:七 集合运算
    SQL:六 函数、谓词、CASE表达式
    SQL:五 复杂查询
    python爬虫——爬取网页数据和解析数据
  • 原文地址:https://www.cnblogs.com/a1b3c7d9/p/11205563.html
Copyright © 2011-2022 走看看