首页 > 其他分享 >Codeforces Round 940 (Div. 2) and CodeCraft-23

Codeforces Round 940 (Div. 2) and CodeCraft-23

时间:2024-04-23 09:45:20浏览次数:38  
标签:prime CodeCraft 前缀 23 int bmod Codeforces 贡献 考虑

Codeforces Round 940 (Div. 2) and CodeCraft-23

前四题难度适中,总体还算不错,我想想都能做。E题考察威尔逊和质数筛前缀和算贡献。F题是数据结构,据说很版,还没补。

A题:题意:给出n个木棍,最多组成多少个多边形

Solution:统计各长度木棍的数量,全部贪心成三角形

void solve(){
	cin>>n;
	for(int i=1;i<=n;i++)cin>>a[i];
	map<int,int>mp;
	for(int i=1;i<=n;i++)mp[a[i]]++;
	int ans=0;
	for(auto [x,y]:mp)ans+=y/3;
	cout<<ans<<endl;
}

B:题意:给出n和k,要求把k拆成n个非负整数,希望最大化n个数的或和的二进制的1的数量

Solution:对于n=1进行特判,无法拆分。从一般情况考虑我们只需要找到k的最高的二进制的位的数tmp=(1<<__lg(k))-1,和k-tmp,剩下的数全部为0.考虑这种情况的代价是把最高位的1消耗去获得低位所有的1.

上述贪心显然存在反例就是舒适就是二进制全1的,那么我们考虑特判这类数即可。代码实现过程中直接对两种构造的答案取max,谁大就用谁的构造方案

int cal(int x){
	int res=__builtin_popcount(x);
	return res;
}
void solve(){
	int k;cin>>n>>k;
	if(n==1){
		cout<<k<<endl;
		return ;
	}
	int len=__lg(k);
	int ans=cal(k);
	int tmp=(1<<len)-1;
	if(ans>=cal(tmp)){
		cout<<k<<" ";
		for(int i=1;i<=n-1;i++)cout<<0<<" ";
	}
	else {
		cout<<tmp<<" "<<k-tmp<<" ";
		for(int i=1;i<=n-2;i++)cout<<0<<" ";
	}
	cout<<endl;
}

C:题意:人和电脑在正方形网格图里下国际象棋。人每次放白车,人放(x,y),电脑放黑车(y,x).如果人放对角线,电脑不回应,人继续先手。一个车所在一行一列不能出现第二个车。

现在棋盘大小,给出前k步棋谱,求最终局面有多少种局面

Solution:考虑给出递推的证明。首先注意到问题只和当前还有几行几列空闲有关,已经被占领的行无法对方案做出贡献。考虑现在填一个n行n列的空白棋盘。由于顺序与最终方案无关,所以根据任意性,我们假设考虑第一步就在第n行落子,也就是说第n行的落子可能是在第j步,当前钦定第一步放,就去除了重复局面 对计算造成的影响。

\(dp[n]=dp[n-1]+2*(n-1)*dp[n-2]\).含义是如果落子在第n行的对角线则问题划归到n-1规模,如果落子在第n行非对角线,则电脑对应位置落黑车,会减少两行两列,问题划归到n-2规模.考虑可以在第n列对称,方案数直接*2.

int dp[N];
 
 
void solve(){
	//cout<<dp[3]<<endl;
	int k;
	cin>>n>>k;
	for(int i=1;i<=k;i++){
		int x,y;cin>>x>>y;
		if(x==y)n-=1;
		else n-=2;
	}
	
	cout<<dp[n]<<endl;
}

D题意:\(\left(\bigoplus_{x\le i\le z} a_i \right)\oplus a_y > \left(\bigoplus_{x\le i\le z} a_i \right)\),求满足条件的x,y,z有多少对,其中\(x<=y<=z\)

首先套路的,对于区间异或和提前预处理前缀异或和,考虑不等式成立条件,从\(a_{y}\)的二进制最高位考虑,当对应区间异或和该位为0的时候不等式成立。为0的条件的区间异或和两个端点需要同时为1或者为0.

所以我们可以预处理拆位的前缀和,后缀和,每次统计的是1的数量,0的数量作为补集也很好得到。

onst int len=__lg((ull)2e9);
bitset<5>b;
//a_{y}^t>t  考虑a_{y}的最高位,如果t这位为0,那么不等式成立。
//如果t这位为1,不等式一定不成立
//考虑枚举y,然后看他左边和右边的这一位的前缀和有多少异或结果为0
//拆位前缀和,后缀和,快速统计数量
void solve(){
	cin>>n;
	for(int i=1;i<=n;i++)cin>>a[i];
	vector<int>s(n+1,0);
	for(int i=1;i<=n;i++)s[i]=s[i-1]^a[i];
vector<vector<int>>pre(n+2,vector<int>(len+2,0));
vector<vector<int>>suf(n+2,vector<int>(len+2,0));
	for(int i=1;i<=n;i++){
		for(int j=len;j>=0;j--){
			int u=(s[i]>>j)&1;
			if(u==1)pre[i][j]=1;
			}
	}
	for(int i=n;i>=1;i--){
		for(int j=0;j<=len;j++){
			suf[i][j]=suf[i+1][j]+pre[i][j];
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=0;j<=len;j++){
			pre[i][j]+=pre[i-1][j];
		}
	}
	int ans=0;
	// for(int i=1;i<=n;i++){
		// b=s[i];
		// cerr<<b<<endl;
	// }
	for(int i=1;i<=n;i++){
		
		int u=__lg(a[i]);
		int c1=pre[i-1][u];
		int c2=suf[i][u];
	//	cerr<<u<<" "<<c1<<" "<<c2<<endl;
		ans+=c1*c2;
		//考虑这里0也可以作为本位为0贡献
		ans+=(max(i-c1,0LL))*(max(n-i+1-c2,0LL));
	}
	cout<<ans<<endl;
}

E:定义一种F运算,求\(\sum\limits_{i=1}^n \sum\limits_{j=1}^i \left( F(i,j) \bmod j \right).\)给出\(F(i,j)\)的定义是从i个元素中选j个元素进行圆排列的方案数。显然\(F(i,j)=C(i,j)*(j-1)!\)

Solution:我们需要进一步变形上面式子\(F(i,j) \bmod j = \frac{i(i-1)\cdots(i-j+1)}{j} \bmod j = \left( (j-1)! \times \left\lfloor \frac{i}{j} \right\rfloor \right) \bmod j\)

考虑对将组合数拆成阶乘,然后发现分子连续j项一定构成modj的剩余系,所以可以进一步化简成下取整形式。

  • 考虑威尔逊定理,对于所有质数\((j-1)! \equiv -1 \bmod j\)
  • 对于所有大于4的合数,\((j-1)! \equiv 0 \bmod j\)

因此我们需要计算对于固定质数j,不同的i对其的贡献,这里就是交换了求和次序。

对于固定j,不同的i造成的贡献如何快速计算?

一般地,对于i从kp到k(p+1)-1,他们的贡献是相同的,我们希望这段i每个数都加上-k modj的贡献,静态区间加我们使用差分维护贡献。最后我们求一遍前缀和得到每个i的贡献,再求一遍得到前n个数的贡献,也就是答案了

我们还需要对4进行单独计算,作为特例。

int minp[N];
int prime[N];
int cnt=0;
int ans[N];
int g[N];
//打表固然美丽,但数学推导更为重要,推出数学式子才理解他们说的打表规律的本质
//题解写的很不错
//总的来说就是先推数学式子用威尔训化解,对于4特判。
//对于所有质数算贡献,交换求和次序,统计答案差分后,前缀和求出所有答案
void init(){
	for (int i = 2; i < N; i++)minp[i] = i;//通过这个初始化省下bool数组空间
        int cnt = 0;
     for (int i = 2; i < N; i++) {
    if (minp[i] == i) prime[cnt++] = i;
    for (int j = 0; j < cnt && prime[j] * i < N; j++) {
        minp[prime[j] * i] = prime[j];
        if (i % prime[j] == 0) break;
        }
}
      for(int i=0;i<cnt;i++){
	       int p=prime[i];
	   //    if(p<300)cerr<<p<<endl;
	       for(int j=p;j<=1000000;j+=p){
	     int u=-j/p;u=(u%p+p)%p;
	       // int u = (p - ((j / p) % p)) % p;
	       //	if(j<100)cerr<<p<<" "<<u<<endl;
	       g[j]+=u;g[j]%=mod;
	      if(j+p<N){g[j+p]-=u;g[j+p]+=mod;g[j+p]%=mod;}
	       }
  }
           int p=4;
            for (int j=4;j<=1000000;j+=4){
      	     
	       	 int u=2*j/p;u%=p;
	          g[j]+=u;g[j]%=mod;
	         if(j+p<N){g[j+p]-=u;g[j+p]+=mod;g[j+p]%=mod;}
	       }
	       
	       
	       for(int i=1;i<=1000000;i++){
	       	g[i]+=g[i-1];g[i]%=mod;
	       	ans[i]=ans[i-1]+g[i];ans[i]%=mod;
	       }
	       
}

标签:prime,CodeCraft,前缀,23,int,bmod,Codeforces,贡献,考虑
From: https://www.cnblogs.com/mathiter/p/18152161

相关文章

  • 界面组件DevExpress Blazor UI v23.2 - 支持.NET 8、全新的项目模版
    DevExpress BlazorUI组件使用了C#为BlazorServer和BlazorWebAssembly创建高影响力的用户体验,这个UI自建库提供了一套全面的原生BlazorUI组件(包括PivotGrid、调度程序、图表、数据编辑器和报表等)。DevExpress Blazor控件目前已经升级到v23.2版本了,新版本正式支持.NET8、拥......
  • 【专题】2023年中国社会办口腔医疗企业报告PDF合集分享(附原数据表)
    原文链接:https://tecdat.cn/?p=34300原文出处:拓端数据部落公众号口腔健康是整体健康的重要基石,当前,无论是哪个年龄段的人群,或多或少都会受到口腔问题的困扰。随着国民口腔健康意识的不断提高,消费者对口腔医疗服务的需求日益多元化,口腔医疗行业也迎来了快速发展阶段。阅读原文,获......
  • Codeforces 1863F Divide, XOR, and Conquer
    记\(s_{l,r}=\oplus_{i=l}^ra_i\)。考虑到这个相当于是\([l,r]\)内分裂区间,可以考虑区间\(\text{DP}\)。即记\(f_{l,r}\)为\([l,r]\)区间是否能被遍历到。转移考虑对于\([l,r]\),考虑在已知的条件下(\(len\ger-l+1\))\([l,r]\)是否合法。即到这个状态......
  • Codeforces Round 940 (Div. 2) and CodeCraft-23 (补题中的小白)
    A.Stickogon思路:Code:#include<bits/stdc++.h>usingnamespacestd;voidsolve(){intn;cin>>n;map<int,int>mp;for(inti=1,x;i<=n;i++){cin>>x;mp[x]++;}intans=0;f......
  • pycharm破解安装激活2023-06最新教程(附破解工具及激活码)
    pycharm破解安装激活2023-06最新教程(附破解工具及激活码) 先去官网安装pycharm:https://www.jetbrains.com.cn/pycharm/download/#section=windows我这里下载的是最新版本2023.1.2,2021年以上的版本都支持此教程破解。先讲安装再讲破解。  点next 选好路径然后nex......
  • The 18-th Beihang University Collegiate Programming Contest (BCPC 2023) - Final
    https://codeforces.com/gym/104883A#include<bits/stdc++.h>usingnamespacestd;usingi32=int32_t;usingi64=longlong;usingvi=vector<int>;i32main(){ios::sync_with_stdio(false),cin.tie(nullptr);i64n,sum=0;c......
  • CSP 2023 游记
    非常好csp,使我RP旋转。没挂分但也没发挥超常,分数看来不算低。针不戳。Day-6~-2一直在打板子,同时写了篇板子博。后面效率有点低就鸽掉了。心情不是很稳定,有点心不在焉,效率被猫薄纱,%。whk的话精神状态也不是很好。把除了dp和网络流的板子几乎都打了一遍,感觉捡回了许......
  • NOIp 2023 游记
    前转广西是弱省,所以广西的初中OIer自然都是低能儿,能参加NOIp,自然不是自己的实力了。\(\phantom{\small\textsf{在弱省学OI,就像,只能获得一个相对失败的人生。}}\)CSP-S:100+0+0+5=105,T2因为数组开太大挂了35分。刚好复赛1=、作为初中生可以参加NOIp。真幸运啊。......
  • Codeforces Round 940 (Div. 2) and CodeCraft-23
    目录写在前面ABCDE写在最后写在前面比赛地址:https://codeforces.com/contest/1957。大病场妈的A签到。尽可能凑三角形。///*By:Luckyblock*/#include<bits/stdc++.h>#defineLLlonglong//=============================================================//======......
  • Codeforces Round 940 (Div. 2)
    这场还挺Edu的C.HowDoestheRookMove?Problem-C-Codeforces数学方法​ 我用的数学方法,卡了很久才推出来思路和式子。​ 首先行列其实等价,直接单考虑剩余\(n\)行就行。​ 这类题应该选择先选一个东西,然后处理剩下的东西。​ 这里好做的方法是先选\(m\)个......