[NOIP2017模拟]举办比赛

2017.8.27 T1 1946

样例数据1
输入

5 5 1 2 3 4 5

输出

3818396440

样例数据2
输入

10000000 10000000 555 888 777 666 12345

输出

4134418848

分析:第一次做这种随机概率题……看到数据那么大O(n)的做法根本想不到就直接放弃了。结果就是个撞运气的FFFFFFF!因为新读入一个数。如果比最小值大,不影响;如果读入值比最小值还小,更新最小值,也不影响,只有在最小值所在的点的值被改大的时候重新扫一遍找到最小值……
ps.可以小优化,记录最小值的s有多少个,这样,只有在最小值的s被改完的时候才会再次扫描,更快一些。

代码
优化后

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;

#define uint unsigned int

inline int getint()
{
    int sum=0,f=1;
    char ch;
    for(ch=getchar();(ch<'0'||ch>'9')&&ch!='-';ch=getchar());
    if(ch=='-')
    {
        f=-1;
        ch=getchar();
    }
    for(;ch>='0'&&ch<='9';ch=getchar())
        sum=(sum<<3)+(sum<<1)+ch-48;
    return sum*f;
}

const int INF=2147483647;
uint x0,x1,a,b,c,n,m;
uint now=1,tot=0,mins,minnum=0,tot1=10000000;
uint s[10000010];

inline uint nxt()
{
    uint t=x0*a+x1*b+c;
    x0=x1;
    x1=t;
    return x0>>2;
}

int main()
{
    freopen("contest.in","r",stdin);
    freopen("contest.out","w",stdout);

    n=getint();m=getint();x0=getint();x1=getint();a=getint();b=getint();c=getint();
    for(int i=0;ifor(int i=1;i<=m;++i)
    {
        int f=nxt();
        int g=nxt();
        int ps=f%n;
        if(s[ps]==ans&&g!=ans) tot1--;
        s[ps]=g;
        if(g==ans) tot1++;
        if(g1;
        if(tot1==0)
        {
            ans=s[0];tot1=1;
            for(int i=1;iif(ans>s[i])
                {
                    ans=s[i];
                    tot1=1;
                }
                else if(s[i]==ans) tot1++;
        }
        now*=10099;
        tot+=now*ans;
    }

    cout<return 0;
}

本题结。

你可能感兴趣的:([NOIP2017模拟]举办比赛)