牛客暑假4 D Jobs (Easy Version) 【前缀异或和】【状态压缩】

本文讲述了小马在编程比赛中获得金奖后收到多家公司的工作邀请。每个公司有不同的职位,每个职位都有对智商(IQ)、情商(EQ)和逆境商(AQ)的最低要求。只要满足至少一个职位的要求,公司就会发出工作邀请。文章还介绍了如何根据朋友的IQ、EQ和AQ生成数据,并给出了一种计算每个朋友收到工作邀请数量的方法。最后提供了一个示例来说明这个过程。
摘要由CSDN通过智能技术生成

 链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

Note: The only difference between the easy and the hard version is the constraints on nnn and mim_imi​.


Since Little Horse gets a golden prize in a programming contest, many companies send offers to him. There are nnn companies, and the iii-th company has mim_imi​ available jobs. To get an offer from a company, you need to be qualified for the job.

How to be qualified? The company will test your "three quotients": IQ (Intelligence Quotient), EQ (Emotional Quotient), and AQ (Adversity Quotient). Each job has three lower limits of the three quotients respectively. If all of your IQ, EQ, and AQ are no less than the corresponding lower limits, you are qualified for the job. As long as you are qualified for at least one job in a company, the company will send an offer to you.
 

Little Horse's three quotients are all high enough, so all the companies send offers to him. But Little Horse has qqq friends that worry about their jobs. Given the value of IQ, EQ and AQ of each friend, Little Horse wants to know how many companies will send offers to each friend.

In this problem, the IQEQ, and AQ of these qqq friends are generated as below.

First, register an mt19937\texttt{mt19937}mt19937 random engine rng\texttt{rng}rng with the seed\texttt{seed}seed and a uniform integer distribution object.

#include <random>
std::mt19937 rng(seed);
std::uniform_int_distribution<> u(1,400);

Then, the value of IQ, EQ, and AQ are generated as follows.

int lastans=0;
for (int i=1;i<=q;i++)
{
    int IQ=(u(rng)^lastans)%400+1;  // The IQ of the i-th friend
    int EQ=(u(rng)^lastans)%400+1;  // The EQ of the i-th friend
    int AQ=(u(rng)^lastans)%400+1;  // The AQ of the i-th friend
    lastans=solve(IQ,EQ,AQ);  // The answer to the i-th friend
}

输入描述:

The first line of input contains two integers n,qn,qn,q (1≤n≤101 \le n \le 101≤n≤10, 1≤q≤2×1061 \le q \le 2\times 10^61≤q≤2×106), indicating the number of companies and Little Horse's friends.

Then in the next nnn lines, the first integer of the iii-th line is mim_imi​ (1≤mi≤1051 \le m_i \le 10^51≤mi​≤105) --- the number of jobs in the iii-th company. Then there follow 3mi3m_i3mi​ integers. The jjj-th triple integers aj,bj,cja_j,b_j,c_jaj​,bj​,cj​ (1≤aj,bj,cj≤4001 \le a_j,b_j,c_j \le 4001≤aj​,bj​,cj​≤400) indicate the lower limits of IQ, EQ, and AQ for the jjj-th job in the iii-th company.

The next line contains one integer seed\text{seed}seed (108≤seed<23110^8\le \text{seed}<2^{31}108≤seed<231). Then the IQ ,EQ, and AQ of these qqq friends are generated as above.

输出描述:

Let's denote the answer to the iii-th friend as ansi\text{ans}_iansi​. You should output:

(∑i=1qansi⋅seedq−i) mod 998244353\left( \sum_{i=1}^q\text{ans}_i\cdot\text{seed}^{q-i} \right) \bmod 998244353(∑i=1q​ansi​⋅seedq−i)mod998244353

in a single line.

示例1

输入

复制3 5 2 1 1 2 2 1 2 3 1 3 2 2 3 1 2 3 3 2 2 3 1 3 2 1 191415411

3 5
2 1 1 2 2 1 2
3 1 3 2 2 3 1 2 3 3
2 2 3 1 3 2 1
191415411

输出

复制34417749

34417749

说明

The value of IQ, EQ, and AQ of the 555 friends in example are shown as follows.

92 108 303
116 36 265
255 132 185
360 219 272
8 115 254

The answers to each friend are all 333.

 

/*
首先,n的范围很小,只有10
所以状态压缩,也不会很大。
*/


#include <iostream>
#include <random>
using namespace std;

typedef long long LL;
const int MAXN=410,mode=998244353;
int n,q;
int seed;
int dp[MAXN][MAXN][MAXN];


LL qmi(int a,int k,int mode)
{
    LL res=1;
    while(k)
    {
        if(k&1) 
        {
            res=res*a%mode;
        }
        a=(LL)a*a%mode;
        k>>=1;
    }
    
    return res%mode;
}


int solve(int state)
{
  
    LL cnt=0;
    while(state)  //求state 里面1的个数
    {
        if(state&1) cnt++;
        state>>=1;
    }
    
    return cnt;
}



int main()
{

    scanf("%d%d",&n,&q);
    
    for(int i=1;i<=n;i++)
    {
        int m;
        scanf("%d",&m);
        for(int j=1;j<=m;j++)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
           dp[a][b][c]|=(1<<(i-1));
        }
    }
    
   for(int i=1;i<MAXN;i++)
       for(int j=1;j<MAXN;j++)
           for(int k=1;k<MAXN;k++)
           {
               dp[i][j][k]|=dp[i-1][j][k];
               dp[i][j][k]|=dp[i][j-1][k];
               dp[i][j][k]|=dp[i][j][k-1];
           }
    
    
    scanf("%d",&seed);
    std::mt19937 rng(seed);
    std::uniform_int_distribution<> u(1,400);
    
    LL sum=0;
    LL lastans=0;
    for (int i=1;i<=q;i++)
    {
    int IQ=(u(rng)^lastans)%400+1;  // The IQ of the i-th friend
    int EQ=(u(rng)^lastans)%400+1;  // The EQ of the i-th friend
    int AQ=(u(rng)^lastans)%400+1;  // The AQ of the i-th friend
    lastans=solve(dp[IQ][EQ][AQ]);  // The answer to the i-th friend
    sum=(sum+(lastans*qmi(seed,q-i,mode)%mode))%mode;
    }
    

    
    printf("%lld\n",sum);
    
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值