• HDU6040 Hints of sd0061


    题目链接:https://vjudge.net/problem/HDU-6040

    题目大意:

      给出 (n) 个数,有 (m) 次询问,每次询问这 (n) 个数中第 (k+1) 大的数是什么。

      另有附加限制:对于 (n) 个数中的任意三个数 (a,b,c),如果满足 (a ot= b, a < c, b < c),则有 (a + b le c).

      ((1 le n le 10^{7}, 1 le m le 100))

    解题思路:

      由附加限制不难联想到斐波那契数列,由于 (F(36) = 14930352),所以我们不难推测将这 (m) 次询问中去重后剩下的不同询问的个数是少于 (36) 的。

      在此,还要再介绍一个优秀的函数:nth_element. 其用法是:nth_element((first, nth, last, compare));作用是:将第 (n) 大的元素放在位置 (n)(从0开始),处理完之后,默认排在它前面的元素都不比它大,排在它后面的元素都不比它小。如果有定义 (compare()) 函数的话,大小关系则由 (compare()) 定义。时间复杂度是 (O(n)).

      于是,一种优秀的做法是:将 (m) 个询问排序,去重,然后从大往小处理询问,用 nth_element() 求出区间第 (k) 大的数,并且将排在第 (k) 大的数后面的数都丢掉。

      最后,这是第 (1000) 题。悄悄地,为自己鼓个掌 (XD)

    AC代码:

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 typedef long long LL;
     5 const LL MOD=1e9+7;
     6 const int MAXN=1e7+5;
     7 const int LIM=1e6;
     8 
     9 unsigned x,y,z;
    10 unsigned rng61() {
    11   unsigned t;
    12   x ^= x << 16;
    13   x ^= x >> 5;
    14   x ^= x << 1;
    15   t = x;
    16   x = y;
    17   y = z;
    18   z = t ^ x ^ y;
    19   return z;
    20 }
    21 int add,n;
    22 unsigned a[MAXN],ta[MAXN];
    23 struct ask{
    24     int ind,pos;
    25 }b[110];
    26 bool cmp(const ask &x,const ask &y){
    27     return x.ind<y.ind;
    28 }
    29 unsigned ans[110];
    30 
    31 int main(){
    32 //    freopen("in.txt","r",stdin);
    33     int m,kase=1;
    34     unsigned A,B,C;
    35     while(scanf("%d%d%u%u%u",&n,&m,&A,&B,&C)==5){
    36         add=0;
    37         x=A,y=B,z=C;
    38         for(int i=0;i<n;i++)
    39             a[i]=rng61();
    40         for(int i=0;i<m;i++){
    41             scanf("%d",&b[i].ind);
    42             b[i].pos=i;
    43         }
    44         sort(b,b+m,cmp);
    45         b[m].pos=m,b[m].ind=n;
    46 
    47         for(int i=m-1;i>=0;i--){
    48             if(b[i].ind==b[i+1].ind)
    49                 ans[b[i].pos]=ans[b[i+1].pos];
    50             else{
    51                 nth_element(a,a+b[i].ind,a+b[i+1].ind);
    52                 ans[b[i].pos]=a[b[i].ind];
    53             }
    54         }
    55         printf("Case #%d:",kase++);
    56         for(int i=0;i<m;i++)    printf(" %u",ans[i]);
    57         printf("
    ");
    58     }
    59     return 0;
    60 }
    “这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。”
  • 相关阅读:
    第五届河南省大学生程序设计竞赛 :最强DE战斗力(大数乘法)
    zzuli2455: 最大增区间(一)
    zzuli2455: 最大增区间(一)
    zzuli2424: 越靠近,越幸运(dfs)
    菜根谭#31
    菜根谭#30
    菜根谭#29
    菜根谭#28
    菜根谭#27
    菜根谭#26
  • 原文地址:https://www.cnblogs.com/Blogggggg/p/9255841.html
Copyright © 2020-2023  润新知