“蔚来杯“2022牛客暑期多校训练营4 Jobs (Easy Version)

分析:此题a[i],b[i],c[i]范围只有400,因此可以设一个三维数组dp[i][j][k]
dp[i][j][k]表示当一个人的IQ为i,EQ为j,AQ为k时可被dp[i][j][k]家公司录取
再考虑,如何表示被几家公司录取,即dp[i][j][k]
若采用加法,会发现公司可能会重复计算
如: 当dp[2][2][2]时可被1,2公司录取,dp[3][3][3]时可被1,2,3公司录取
采用加法 dp[4][4][4] 则会至少会重复计算2公司一次,故不可以
正确采用异或,用1<<i是否等于1表示能否被第i家公司录取
则dp[i][j][k]=dp[i][j][k] | dp[i-1][j][k] |dp[i][j-1][k] | dp[i][j][k-1]
代码:

#include<bits/stdc++.h>
#include <random>
 
using namespace std;
 
const int MXN=407;
const long long mod=998244353;
int n;
int dp[MXN][MXN][MXN];
 
 
 
int fun(int x){
	int cnt=0;
	while(x){
		if(x&1)cnt++;
		x>>=1;
	}
	return cnt;
}
 
long long fast(long long x,int s){
	long long res=1,tmp=x;
	while(s){
		if(s&1) res=res*tmp%mod;
		tmp=tmp*tmp%mod;
		s>>=1;
	}
	return res;
}
int main(){
	ios::sync_with_stdio(false);
	int q,i,j,k,seed,m,a,b,c,sum;
	long long res=0;
	cin>>n>>q;
	for(i=1;i<=n;i++){
		cin>>m;
		for(j=1;j<=m;j++){
			cin>>a>>b>>c;
			dp[a][b][c]|=(1<<(i-1));
		}
	}
	for(i=1;i<MXN;i++){
		for(j=1;j<MXN;j++){
			for(k=1;k<MXN;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];
			}
		}
	}
	cin>>seed;
	std::mt19937 rng(seed);
    std::uniform_int_distribution<> u(1,400);
    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=fun(dp[IQ][EQ][AQ]);// The answer to the i-th friend
        res=(1ll*res+(lastans*fast(seed,q-i)%mod))%mod;
    }
    cout<<res<<"\n";
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值