zoukankan      html  css  js  c++  java
  • 中位数的和_KEY

    中位数的和

    (number.pas/c/cpp)

    【题目描述】

    flower 有 N-1 个朋友,他们要一起玩一个游戏:首先确定三个非负整数 a,b,c,然后每个人依次在纸上写一个数,设第 i 个人写下的数字为 f[i],flower 先写下数字 f[1]=1,对于第 i 个写数字的人(i>1)有: f[i]=(a*m[i-1]+b*i+c)mod1,000,000,007;其中 m[i-1]为前 i-1 个写下的数字的中位数,如果 i-1 为偶数,那么取靠前的那个数。flower 想要知道,所有人写下的数字的和。

    【输入格式】

    输入仅一行,包含四个非负整数 a,b,c,N;意义如上;

    【输出格式】

    输出只有一行一个整数,表示数字和。

    【输入样例】

    3 1 2 6

    【输出样例】

    103

    【数据规模】

    对于 30%的数据: N≤1,000;

    对于 100%的数据: N≤200,000; a,b,c≤1,000,000,007。

    第一次拿到这道题,给我的感觉是F[1~i-1]一定比F[i]小,所以中位数一定是F[i>>1](CJJDs也是这样想的),但马上被我否认了,因为我注意到有一个mod,所以值可能会变小。于是立马换一种思路,既然叫我们求中位数,即中间的数,那么我们将已存的有序数列掰成两半,中间的即为中位数。那么这里就需要用到一个大根堆,用于存储前半段数,一个小根堆,用于存储后半段数。每次将生成的数放入小根堆,如果当前是第i次操作且i为奇数,那么将小根堆顶放入大根堆。注意mod后如果小于大根堆顶就交换。

    code

    #include <cstdio>
    #include <cctype>
    #include <queue>
    #define mod 1000000007
    #define C c = tc ( )
    using namespace std;
    
    inline char tc(){
        static char fl[100000],*A,*B;
        return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
    }
    
    inline void read(long long &x){
        static char c;
        while(!isdigit(C));x=c-'0';
        while(isdigit(C))x=x*10+c-'0';
    }
    
    long long a,b,c,n;
    long long f[200001];
    priority_queue<long long>w1;
    priority_queue<long long,vector<long long>,greater<long long> >w2;
    
    int main(){
    
        freopen("number.in","r",stdin);
        freopen("number.out","w",stdout);
    
        read(a),read(b),read(c),read(n);
        w1.push(f[1]=1);
            for(int i=2;i<=n;i++){
                long long val=w1.top(),ve;
                f[i]=(val*a+b*i+c)%mod;ve=f[i];
                if(ve<val)w1.pop(),w1.push(ve),ve=val;
                w2.push(ve);
                if(i&1)val=w2.top(),w2.pop(),w1.push(val);
            }
        long long ans=0;
            for(int i=1;i<=n;i++)ans+=f[i];
        printf("%lld",ans);
    
        fclose(stdin),fclose(stdout);
        return 0;
    }

    最后引用CJJ的话。

    如果是Pascal的话我也可以,用Pascal打堆!

  • 相关阅读:
    “是懒人造就了方法”——读后感
    多态性动手动脑
    数组问题随笔
    String java问题随笔
    java问题总结
    java问题随笔
    java一些问题的解答
    利用参数的值得返回来求和
    是懒人造就了方法——读后感
    大道至简读后感——JAVA伪代码
  • 原文地址:https://www.cnblogs.com/Cptraser/p/7593452.html
Copyright © 2011-2022 走看看