zoukankan      html  css  js  c++  java
  • Gym 100851G Generators (vector+鸽笼原理)

    Problem G. Generators

    Input file: generators.in

    Output file: generators.out
    Little Roman is studying linear congruential generators — one of the oldest and best known pseudorandom number generator algorithms. Linear congruential generator (LCG) starts with a non-negative integer number x0 also known as seed and produces an infinite sequence of non-negative integer numbers xi (0 ≤ xi < c) which are given by the following recurrence relation:
    xi+1 = (axi + b) mod c
    here a, b, and c are non-negative integer numbers and 0 ≤ x0 < c. Roman is curious about relations between sequences generated by different LCGs. In particular, he has n different LCGs with parameters a(j), b(j), and c(j) for 1 ≤ j ≤ n, where the j-th LCG is generating a sequence x(j) i . He wants to pick one number from each of the sequences generated by each LCG so that the sum of the numbers is the maximum one, but is not divisible by the given integer number k. Formally, Roman wants to find integer numbers tj ≥ 0 for 1 ≤ j ≤ n to maximize s =Pn j=1 x(j) tj subject to constraint that s mod k 6= 0. Input The first line of the input file contains two integer numbers n and k (1 ≤ n ≤ 10000, 1 ≤ k ≤ 109). The following n lines describe LCGs. Each line contains four integer numbers x(j) 0 , a(j), b(j), and c(j) (0 ≤ a(j),b(j) ≤ 1000, 0 ≤ x(j) 0 < c(j) ≤ 1000). Output If Roman’s problem has a solution, then write on the first line of the output file a single integer s — the maximum sum not divisible by k, followed on the next line by n integer numbers tj (0 ≤ tj ≤ 109) specifying some solution with this sum. Otherwise, write to the output file a single line with the number −1.
    Sample input and output
    2 3

    1 1 1 6

    2 4 0 5


    8

    4

    1


    2 2

    0 7 2 8

    2 5 0 6


    -1


    In the first example, one LCG is generating a sequence 1, 2, 3, 4, 5, 0, 1, 2, ..., while the other LCG a sequence 2, 3, 2, 3, 2, ....

    In the second example, one LCG is generating a sequence 0, 2, 0, 2, 0, ..., while the other LCG a sequence 2, 4, 2, 4, 2, ....

    题目中的xi+1是指xi的下一项。

    第四场训练赛的题,是欧洲赛的题,比赛地址:传送门

    题意:n行,每行x,a,b,c,推公式,每一行在这一行当中取一个数使得他们的和最大且不能被k整除,如果不存在输出-1。

    题解:记录第一大和第二大的数,并且第二大的数不能被k整除,求出所有行中与第一个数相差最小的这个第二个数。如果最大的数的所有总和被k整除,就用这个数去换,记得用数组记录选取的数的下标。鸽笼原理最多c个数,如果算过就可以跳出,用动态数组记录。

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <vector>
    using namespace std;
    const int maxn=1e6+5;
    const int mm=100005;
    bool vis[maxn];
    int f1[maxn],f2[maxn];
    int main()
    {
        freopen("generators.in","r",stdin);
        freopen("generators.out","w",stdout);
        int n,k,ans=0,tmp=mm,flag=-1;
        scanf("%d%d",&n,&k);
        for(int i=0; i<n; i++)
        {
    
            int x,a,b,c;
            scanf("%d%d%d%d",&x,&a,&b,&c);
            for(int j=0; j<c; j++)
                vis[j]=0;
            vector <int> data;
            for(int j=0; j<c; j++)
            {
                if(vis[x]) break;
                vis[x]=1;
                data.push_back(x);
                x=(a*x+b)%c;
            }
            int max1=-1,max1i=-1;
            for (int i = 0; i < data.size(); i++)
            {
                if (data[i] > max1)
                {
                    max1 = data[i];
                    max1i = i;
                }
            }
            ans+=max1;
            int max2=-1,max2i=-1;
            int tmp2=max1%k;
            for (int i = 0; i < data.size(); i++)
            {
                if (data[i] > max2&&(data[i]%k)!=tmp2)
                {
                    max2 = data[i];
                    max2i = i;
                }
            }
            f1[i]=max1i;
            f2[i]=max2i;
            int minn=max1-max2;
            if(max2i!=-1&&minn<tmp)
            {
                tmp=minn;
                flag=i;
            }
            //cout<<max1<<"   "<<max2<<endl;
        }
        if(ans%k==0&&flag==-1)
        {
            cout<<-1<<endl;
        }
        else if(ans%k==0)
        {
            f1[flag]=f2[flag];
            ans-=tmp;
            cout<<ans<<endl;
            for(int i=0;i<n-1;i++)
            cout<<f1[i]<<" ";
            cout<<f1[n-1]<<endl;
        }
        else
        {
            cout<<ans<<endl;
            for(int i=0;i<n-1;i++)
            cout<<f1[i]<<" ";
            cout<<f1[n-1]<<endl;
        }
        return 0;
    }
  • 相关阅读:
    空间换时间之反范式设计之路/合理冗余/去除外键
    WebAPI接口设计:SwaggerUI文档 / 统一响应格式 / 统一异常处理 / 统一权限验证
    开放api接口签名验证
    EasyUI开发踩过的坑(EasyUI开发笔记)
    nuget挂了吗?
    C# 实体/集合差异比较,比较两个实体或集合值是否一样,将实体2的值动态赋值给实体1(名称一样的属性进行赋值)
    从应用的角度讲创业公司该如何选择域名?
    疑似easyui本身bug:easyui时间控件问题,试了几个版本都不行
    工作三年对程序的理解特来求证
    控制器读取视图表单中的数据的几种方式
  • 原文地址:https://www.cnblogs.com/Ritchie/p/5727080.html
Copyright © 2011-2022 走看看