zoukankan      html  css  js  c++  java
  • [20190925机房测试] 不正常序列

    我们定义一个不正常数列
    F[1]=1
    F[i]=(a*M+b*i+c) mod (1e9+7)
    其中,M是指数列 { F[i] } 的中位数
    如果数列一共有偶数项,那么我们定义较小的那个为他的中位数
    对于给定的a,b,c和n,求数列F[i]之和
    

    一句话题意:实时更新数列并查询数列中位数

    很显然,我们可以用两个堆,储存这个数列的前半部分和后半部分
    这两个堆的堆顶就是中位数了(具体是哪个堆的堆顶要分情况)
    但这样时间复杂度不优秀,优化的方法如下:
    在两个堆之间连一个数组,作为“缓冲区”
    那么每次加入新数的时候,有可能只是数字在缓冲区上移动
    并不涉及堆的操作,就可以优化时间复杂度

    堆可以使用优先队列实现

    代码:

    #include<bits/stdc++.h>
    #define mod 1000000007
    #define size1 q1.size()
    #define size2 q2.size()
    #define ll long long
    using namespace std;
    
    ll a,b,c,n,mid,ans;
    ll f[2000005];
    priority_queue<ll> q1;//前面一半的数 
    priority_queue<ll,vector<ll>,greater<ll> > q2;//后面一半的数 
    
    template<class T>inline void read(T &res)
    {
    	char c;T flag=1;
    	while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
    	while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
    }
    
    void insert(ll x)
    {
    	x<=q1.top() ? q1.push(x) : q2.push(x);
        if(size1>size2&&size1-size2>1)
    	{
    		q2.push(q1.top());
            q1.pop();
        }
        else if(size1<size2)
    	{
    		q1.push(q2.top());
            q2.pop();
        }
        return;
    }
    
    int main()
    {
        freopen("unnormal.in","r",stdin);
        freopen("unnormal.out","w",stdout);
    	read(a);read(b);read(c);read(n);
        f[1]=1; q1.push(1);
        for(register int i=2;i<=n;++i)
    	{
    		mid=q1.top();
            f[i]=(a*mid+b*i+c)%mod;
            insert(f[i]);
        }
        for(register int i=1;i<=n;++i) ans+=f[i];
        printf("%lld
    ",ans);
        return 0;
    }
    

    考试的时候WA了7个点,因为答案 (ans) 并没有要求取模
    毒瘤出题人。。。

  • 相关阅读:
    西安.NET俱乐部群 推广代码
    跟我学Makefile(六)
    跟我学Makefile(五)
    跟我学Makefile(四)
    跟我学Makefile(三)
    跟我学Makefile(二)
    Kconfig文件说明2
    Kconfig文件说明
    kernel内核配置说明
    makefile中ifeq与ifneq dev/null和dev/zero简介 dd命令
  • 原文地址:https://www.cnblogs.com/tqr06/p/11586994.html
Copyright © 2011-2022 走看看