ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

"蔚来杯"2022牛客暑期多校训练营4

2022-07-31 10:33:42  阅读:134  来源: 互联网

标签:粒子 方差 int 蔚来 多校 long 牛客 include mod


N-Particle Arts

题意

有n个粒子,第i个粒子有\(a_i\)的能量。粒子之间不停的碰撞,当两个分别具有能量a,b的两个粒子相撞之后这两个粒子会消失,同时产生两个能量分别为a&b,a|b,的粒子。当这些粒子的状态稳定之后求它的能量的方差是多少。(稳定是指方差不再改变)

数据范围

\(1 <= n <= 1e5 , 0 <= a_i < 2^{15}\)

思路

性质一:\(a \& b + a|b = a + b\),所以能量的平均值\(E(x)\)不变

性质二:方差公式有\(\sigma^2 = \frac{1}{n}\sum(a_i-E(x))^2\) 同时还有\(D(x) = E(x^2) - {E(x)}^2\)这道题就要用第二个,不然会溢出。

性质三:题中说,方差不会变小,所以稳定状态的方差一定是最大的。

稳定状态下会有\(a\&b = a\)或者\(a\&b = b\)即a,b中二进制集有包含关系。若将其从小到大排序,对于二进制集会有\(a_i \subseteq a_{i+1}\)。如此,对于每一个二进制来讲,前1~k全是0 k+1~n全是1。

具体做法就是,统计每个二进制位中1出现的次数,记为cnt[j]。从后往前扫一遍数组,枚举每个二进制位,若cnt[j]有剩余,就取出一个让该位置的数的第j位为1,否则为0.

注:代码中是相当于从大到小排序。

#include<algorithm>
#include<iostream>
using namespace std;
const int N = 1e5+10;
int n;
int A[N] , bcnt[15];
int main()
{
	unsigned long long Ex = 0 , Ex2 = 0 , tmp , res1 , res2;
	cin >> n;
	for(int i = 1 ; i <= n ; ++i)
	{
		cin >> A[i]; Ex += A[i];
		for(int j = 0 ; j < 15 ; ++j) if((A[i] >> j) & 1) bcnt[j]++;
	}
	for(int i = 1 ; i <= n ; ++i)
	{
		tmp = 0;
		for(int j = 0 ; j < 15 ; ++j) if(bcnt[j])
			tmp = tmp | (1 << j) , bcnt[j]--;
		Ex2 += tmp * tmp;
	}
	res1 = Ex2 * n - Ex * Ex;
	res2 = (unsigned long long)n * n;
	tmp = __gcd(res1 , res2);
	if(res1) cout << res1 / tmp << '/' << res2 / tmp << '\n'; else cout << "0/1" << '\n';
	return 0;
}

Jobs (Easy Version)

题意

有n个公司,每个公司提供\(m_i\)个岗位,每个岗位有三个限制条件IQ,EQ,AQ。只有自己的三个值都大于等于该岗位的限制,该公司才会发offer。现有Q个人问,每个人可以收到几个公司的offer。

数据范围

\(1<=n<=10,1<=m<1e5,1<=Q<=1e6,1<=IQ,EQ,AQ<=400\)

思路

建一个三维数组\(s[i][j][k]\)表示在这个三维前缀里有哪些公司会给offer,第i个公司用(1<<i)表示。

#include<iostream>
#include<random>
using namespace std;
const int mod = 998244353;
int s[401][401][401] , num[1 << 10];
int ksm(int a , int k)
{
	int ans = 1; a %= mod;
	for( ; k ; k >>= 1 , a = (long long)a * a % mod)
		if(k & 1) ans = (long long)ans * a % mod;
	return ans;
}
int main()
{
	int n , Q; scanf("%d%d" , &n , &Q);
	for(int i = 1 ; i <= n ; ++i)
	{
		int num , a , b , c; 
		scanf("%d" , &num);
		for(int j = 1 ; j <= num ; ++j)
		{
			scanf("%d%d%d" , &a , &b , &c);
			s[a][b][c] |= 1 << (i - 1);
		}
	}
	for(int i = 1 ; i < 400 ; ++i)
		for(int j = 1 ; j <= 400 ; ++j)
			for(int k = 1 ; k <= 400 ; ++k)
				s[i+1][j][k] |= s[i][j][k];
	for(int j = 1 ; j < 400 ; ++j)
		for(int i = 1 ; i <= 400 ; ++i)
			for(int k = 1 ; k <= 400 ; ++k)
				s[i][j+1][k] |= s[i][j][k];
	for(int k = 1 ; k < 400 ; ++k)
		for(int j = 1 ; j <= 400 ; ++j)
			for(int i = 1 ; i <= 400 ; ++i)
				s[i][j][k+1] |= s[i][j][k];
	int seed; scanf("%d" , &seed);
	for(int i = 1 ; i < (1 << 10) ; ++i) num[i] = num[i >> 1] + (i & 1);
	mt19937 rng(seed);
	uniform_int_distribution<> u(1,400);
	int lastans = 0 , res = ksm(seed , Q - 1) , inv = ksm(seed , mod - 2) , Ans = 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 = num[s[IQ][EQ][AQ]];
	    Ans = (Ans + (long long)lastans * res % mod) % mod; res = (long long)res * inv % mod;
	}
	printf("%d\n" , Ans);
	return 0;
}

标签:粒子,方差,int,蔚来,多校,long,牛客,include,mod
来源: https://www.cnblogs.com/R-Q-R-Q/p/16536572.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有