首页 > 其他分享 >231112洛谷模拟赛

231112洛谷模拟赛

时间:2023-11-12 20:01:17浏览次数:34  
标签:cnt 231112 int ans 洛谷 mod mx 模拟 define

T1 种树

P9836 种树

只需要运用一些小学奥数即可解决

首先需要知道的一点是将 \(p_i\) 质因数分解后得到 \(p_i = \prod\limits_{j = 1}^m a_j^{k_j}\) ,则有 \(\prod\limits_{i = 1}^{m} (k_i+1)\) 个因数

则最终就是把所有的都再乘起来

考虑 \(w\) 分解后能造成什么影响,依据乘法分配律发现我们要把 \(w\) 的质因数都分给最小的 \(k_i\) (包括 \(k_i\) 为 \(0\) 的情况)便可以做到答案最大

那么只需要开质因数种类数个堆维护最小值就可以了,代码也很好写

#include<bits/stdc++.h>
#define mod 998244353 
#define N 10010
#define pii pair<int,int>
#define fi first
#define se second
using namespace std;
int n,k,w,cnt[N],mx[N],prime[N],tot,a[N],id[N];
priority_queue<int,vector<int>,greater<int> >q[N];
inline void init(){
	mx[0] = mx[1] = 1;
	for(int i = 2;i<=N-10;i++){
		if(!mx[i]) prime[++tot] = i,id[i] = tot,mx[i] = i;
		for(int j = 1;j<=tot&&i*prime[j]<=N-10;j++){
			mx[i*prime[j]] = prime[j];
			if(i%prime[j]==0) break;
		}
	}
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	init();
	cin>>n>>k;
	for(int i = 1;i<=n;i++){
		cin>>a[i];
		while(a[i]!=1){
			cnt[id[mx[a[i]]]]++;
			a[i]/=mx[a[i]];
		}
		for(int j = 1;j<=tot;j++)
			if(cnt[j]){
				q[j].emplace(cnt[j]);
				cnt[j] = 0;
			}
	}
	while(k!=1){
		if(q[id[mx[k]]].size()<n){
			q[id[mx[k]]].emplace(1);
			k/=mx[k];
			continue;
		}
		int u = q[id[mx[k]]].top();q[id[mx[k]]].pop();
		u++;
		q[id[mx[k]]].emplace(u);
		k/=mx[k];
	}
	int ans = 1;
	for(int i = 1;i<=tot;i++){
		while(q[i].size()){
			ans = 1ll*ans*(q[i].top()+1)%mod;
			q[i].pop();
		}
	}
	cout<<ans;
	return 0;
}

T2 汪了个汪

P9837 汪了个汪

题解区第一篇的人类智慧太强了,我就不献丑了,正解是图论,不过不好写

反正我也只会那个人类智慧

#include<bits/stdc++.h>
#define N 4010
using namespace std;
int n,t,a[N][N];
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	cin>>n>>t;
	for(int i = 1;i<=n;i++){
		int len = 1,st = (i&1)?(2*n-i+1)/2:(i>>1);
		for(int j = 1;j<=i;j++){
			cout<<st<<" ";
			if(j&1) st+=len;
			else st-=len;
			len++;
		}
		cout<<"\n";
	}
	return 0;
}

T3 挑战 NPC IV

P9838 挑战 NPC IV

这道题其实并不是很难想前面 \(52\) 分的,只需要考虑到对于 \(k = 2\) 时一定是与 \(k=1\) 的答案一样的就能拿到 \(32\) 分

对于 \(52\) 分来说,你只需要发现 \(n\ge 29\) 时 \(k\le 10^{18}\) 的答案都一样就行

要拿到这几分,首先需要知道一个位置会被计算 \(i\times (n-i+1)\) 次,那么最小的排列就是大的放两端小的放中间

然后你可以发现对于对称的两个位置来说的贡献是一样的,那么就可以交换而使答案不变,所以第一个结论成立

又因为对于位置的排列交换之后会有非常多种,那么在计算一通后就可以发现第二个性质

计算过程去翻题解应该有

其实第二个并不需要花费 \(\mathcal O(n\log n)\) 的时间来模拟排列,只需要大力推导一个式子就可以 \(\mathcal O(\log n)\) 求出答案

那我们剩下的只有 \(n \le 28\) 时的情况了

然后就是一个极为炸裂的 \(dp\) ,对于这个逆天玩意,大家还是看题解吧 我不太懂

所以我写这么多有啥用

#include<bits/stdc++.h>
#define int long long
#define mod 998244353
using namespace std;
int n,k,dp[15][8][5][3][2][6000],inv2 = (mod+1)>>1,inv6 = (mod+1)/6,cnt[70],fac[20];
int dfs(int x,int t1,int t2,int t3,int t4,int t5,int y){
	if(y<0||t1<0||t2<0||t3<0||t4<0||t5<0) return 0;
	if(!y) return t1||t2||t3||t4||t5?0:1;
	int &ans = dp[t1][t2][t3][t4][t5][y];
	if(~ans) return ans;
	ans = 0;
	int p = t1+t2+t3+t4+t5;
	p = p*(x-p+1);
	ans+=dfs(x,t1-1,t2,t3,t4,t5,y-p);
	ans+=dfs(x,t1,t2-1,t3,t4,t5,y-2*p);
	ans+=dfs(x,t1,t2,t3-1,t4,t5,y-3*p);
	ans+=dfs(x,t1,t2,t3,t4-1,t5,y-4*p);
	ans+=dfs(x,t1,t2,t3,t4,t5-1,y-5*p);
	return ans;
}
inline int calc(int x,int y){
	x%=mod;y%=mod;
	int ans = (x+1)*y%mod*(y+1)%mod*inv2%mod;
	ans-=y*(y+1)%mod*(2*y+1)%mod*inv6%mod;
	return (ans+mod)%mod;
}
inline int getans(int x){
	int y = (x>>1),ans = 0;
	for(int i = 0;i<60;i++)
		cnt[i+1] = x>>i;
	for(int i = 1;i<60;i++)
		cnt[i]-=cnt[i+1];
	if(x&1){
		ans = (y+1)%mod*((x-y+mod)%mod)%mod;
		cnt[1]--;
	}
	for(int i = 1;i<=60;i++){
		int t = cnt[i]>>1;y-=t;
		ans = (ans+2*(calc(x,y+t)-calc(x,y)+mod)%mod*i%mod)%mod;
		if(cnt[i]&1){
			ans = (ans+y%mod*((x-y+1+mod)%mod)%mod*i%mod)%mod;
			ans = (ans+y%mod*((x-y+1+mod)%mod)%mod*(i+1)%mod)%mod;
			cnt[i+1]--;y--;
		}
	}
	for(int i = 0;i<60;i++)
		cnt[i+1] = x>>i;
	for(int i = 1;i<60;i++)
		cnt[i]-=cnt[i+1];
	return ans;
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	fac[0] = 1;
	for(int i = 1;i<=15;i++)
		fac[i] = fac[i-1]*i;
	int T;cin>>T;
	while(T--){
		cin>>n>>k;
		int x = getans(n);
		if(n>28){
			cout<<x<<"\n";
			continue;
		}
		for(int i = 1;i<=5;i++)
			k = (k-1)/fac[cnt[i]]+1;
		memset(dp,0xff,sizeof(dp));
		while(1){
			int y = dfs(n,cnt[1],cnt[2],cnt[3],cnt[4],cnt[5],x);
			if(y>=k){
				cout<<x<<"\n";
				break;
			}
			k-=y;x++;
		}
	}
	return 0;
}

T4 四暗刻单骑

不懂麻将

好吧这题咋都不好拿分,不说了

标签:cnt,231112,int,ans,洛谷,mod,mx,模拟,define
From: https://www.cnblogs.com/cztq/p/17827672.html

相关文章

  • 第十五届蓝桥杯模拟赛 -- 删掉m个字符使得字典序最小
    第十五届蓝桥杯模拟赛--删掉m个字符使得字典序最小贪心+单调栈importjava.util.Deque;importjava.util.LinkedList;importjava.util.Scanner;publicclassMain{ publicstaticvoidmain(String[]args){ Scannerscanner=newScanner(System.in); String......
  • [Luogu NOIP 2023 模拟] Solution
    这篇blog在我的博客后台躺了好几天了,只不过今天才记起来发。种树(plant)首先看到因数个数,想到在质因数分解后的序列上考虑问题。进一步观察,每个不同质因子的贡献是独立的。也就是说,我们单独考虑某一个质因子对答案的贡献,是这样的问题:给长度为\(n\)的序列\(a\)和一个数......
  • 红黑树插入节点的模拟实现
    要学习红黑树节点的插入那么首先就要了解什么是红黑树,以及红黑树的特点。红黑树的特点本来AVL树已经很厉害了,但是红黑树的总体效率略比1AVL树高。高的大体原因。我们先来看一下红黑树和AVL树的区别。AVL树严格的保证了左子树和右子树的高度差不超过1,而红黑树则是保证了最长路径不超......
  • 20231112
    前几天实在没有时间没写,我谢罪/kk但是我觉得我也写不出来什么有趣的鲜花qwq昨晚深夜听歌,发现自己的时差真的好大,总是会听一些好几年前的歌,2023听2016的歌是什么操作(虽然我那会还不知道Vocaloid就是了。然后听听听,听到不知道多久就睡着了。于是有了我今天12:30才醒来的这一幕。......
  • 【洛谷 P2669】[NOIP2015 普及组] 金币 题解(循环)
    [NOIP2015普及组]金币题目背景NOIP2015普及组T1题目描述国王将金币作为工资,发放给忠诚的骑士。第一天,骑士收到一枚金币;之后两天(第二天和第三天),每天收到两枚金币;之后三天(第四、五、六天),每天收到三枚金币;之后四天(第七、八、九、十天),每天收到四枚金币……;这种工资发放模式会一直这......
  • 歌谣v2+ele笔记记录JsonServer模拟数据2
    第一步初始化配置npminit-y第二步yarnaddjson-server第三步创建db.json文件{"account":{"user":[{"name":"geyao","password":"123456"}]}}启动json-server--watch.......
  • NOIP2023模拟赛 种树
    NOIP2023模拟赛种树先整无脑爆搜#include<iostream>#include<algorithm>#include<cstdio>#definemod%998244353#definelllonglongconstintN=1e4+10;usingnamespacestd;lln,w;llp[N];llfy[N],nfy;llans=-1;intvis[N];intge......
  • 54. 替换数字(第八期模拟笔试)
    2023-11-11题目页面(kamacoder.com)54.替换数字(第八期模拟笔试)思路:c++可以用双指针,Java字符串是不能改变的,直接用替换importjava.util.Scanner;classMain{publicstaticvoidmain(String[]args){//Strings="a1b2c3";Scanners......
  • 洛谷NOIP2023模拟赛
    种树题目背景小Rf不是很喜欢种花,但他喜欢种树。题目描述路边有\(n\)棵树,每棵树的高度均为正整数,记作\(p_1,p_2\dotsp_n\)。定义一棵树的宽度为它高度的正因数个数,这些树能覆盖的距离为它们宽度的乘积,你想请你的朋友们来乘凉,但你发现这些树能覆盖的距离不够多。......
  • 【洛谷 P1035】[NOIP2002 普及组] 级数求和 题解(循环)
    [NOIP2002普及组]级数求和题目描述已知:。显然对于任意一个整数,当足够大的时候,。现给出一个整数,要求计算出一个最小的,使得。输入格式一个正整数。输出格式一个正整数。样例#1样例输入#11样例输出#12提示【数据范围】对于的数据,。【题目来源】NOIP2002普及组第一题......