首页 > 其他分享 >241114 noip 模拟赛

241114 noip 模拟赛

时间:2024-11-14 20:19:55浏览次数:1  
标签:noip int sum long leq 241114 ans 序列 模拟

省流:\(90 + 100 + 20 + 10\)。t1t2花太久时间了。

T1

题意:给一张 \(n \times m\) 的网格图,\((x,y)\) 与 \((x + 1,y)\) 的边为 \(a_x + b_y\),\((x,y)\) 与 \((x,y + 1)\) 的边为 \(c_x + d_y\)。求这张图的最小生成树的边权和。

\(n,m \leq 10^6\)。

稍微画图注意到,一个点一定跟它的上面和左边的其中一个点之间的边是最小生成树的边。

一列一列的做,这样 \(a,c\) 就是固定的了,那么如果向上的边小于向左的边,则 \(a + b < c + d\),移项得 \(a - c < d - b\),由于不管在那一列,同一行的 \(d - b\) 固定,所以可以直接按照 \(d - b\) 排序,二分找出 \(a - c\) 的分界点,一部分为向上的边,一部分为向左的边,前缀和优化即可。

代码:

#include<bits/stdc++.h>
#define int __int128
using namespace std;
const int N=1e6+5;
int n,m,a[N],b[N],c[N],d[N],pre[N],suf[N],ans=0;
struct node {
	int w,a,b;
	bool operator<(const node &o) const {return w<o.w;}
}x[N];
int read() {
	int x=0;
	char ch=getchar();
	while(!isdigit(ch)) ch=getchar();
	while(isdigit(ch)) {
		x=x*10+ch-'0';
		ch=getchar();
	}
	return x;
}
void write(int x) {
	if(x>9) write(x/10);
	putchar(x%10+'0');
}
signed main() {
	freopen("mst.in","r",stdin);
	freopen("mst.out","w",stdout);
	n=read(),m=read();
	for(int i=1; i<n; i++) a[i]=read();
	for(int i=1; i<=m; i++) b[i]=read();
	for(int i=1; i<=n; i++) c[i]=read();
	for(int i=1; i<m; i++) d[i]=read();
	for(int i=1; i<=n-1; i++) ans+=b[1]+a[i];
	for(int i=1; i<=m-1; i++) ans+=c[1]+d[i];
	for(int i=1; i<m; i++) x[i]=(node){d[i]-b[i+1],d[i],b[i+1]};
	sort(x+1,x+m);
	for(int i=1; i<m; i++) pre[i]=pre[i-1]+x[i].a;
	for(int i=m-1; i>=1; i--) suf[i]=suf[i+1]+x[i].b;
	for(int i=1; i<n; i++) {
		int tmp=a[i]-c[i+1];
		int l=1,r=m-1,pos=m;
		while(l<=r) {
			int mid=l+r>>1;
			if(x[mid].w>=tmp) r=mid-1,pos=mid;
			else l=mid+1;
		}
		ans+=(pos-1)*c[i+1]+pre[pos-1]+(m-pos)*a[i]+suf[pos];
	}
	write(ans);
	return 0;
}

闲话:会炸 long long 也是逆天了。赛时写了 \(90\) 分的部分分而不是写挂/kx

T2

题意:定义一个序列的价值为这个序列本质不同的子序列的个数,给定一个长度为 \(n\) 的序列,求这个序列的所有非空子序列的价值和,对 \(998244353\) 取模。注意子序列是可以不连续的。

\(n \leq 10^6\)。

官方做法:

计算一个序列的本质不同子序列数量显然应该使用子序列自动机,即 fifi​ 表示最后一个数为 ii 的本质不同子序列数量,在序列末尾加入 \(x\) 时的转移为 \(f_x = 1 + \sum_{i = 1}^n f_i​\)。

然后考虑原问题,转化为原序列的每个元素有 \(\frac{1}{2}\)​ 的概率加入计算贡献的序列末尾,上述转移发生与不发生的概率各为 \(\frac{1}{2}\)​,那么此时的转移即为 \(fx=\frac{1}{2}(1+f_x+\sum_{i = 1}^n f_i)\)。

最后输出 \(2^n \sum_{i = 1}^n f_i\)​ 即可。

我的赛时做法:

感觉不太好描述,太蒻了,给个代码。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+5,p=998244353;
int n,a[N],pw[N],dp[N],lst[N],sum[N];
void init(int lim) {
	pw[0]=1;
	for(int i=1; i<=lim; i++) pw[i]=pw[i-1]*2%p;
}
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr),cout.tie(nullptr);
	cin>>n;
	init(n);
	for(int i=1; i<=n; i++) cin>>a[i];
	dp[0]=1;
	for(int i=1; i<=n; i++) {
		if(lst[a[i]]) sum[a[i]]=sum[a[i]]*pw[i-lst[a[i]]-1]%p;
		dp[i]=(dp[i-1]*3%p-sum[a[i]]+p)%p;
		sum[a[i]]=(sum[a[i]]+dp[i-1])%p;
		lst[a[i]]=i;
	}
	cout<<(dp[n]-pw[n]+p)%p;
	return 0;
}

闲话:这题赛时卡我好久。

T3

原题:AT_kupc2018_h。

题意:给定正整数 \(n,m,s\) 和 \(m\) 个三元组 \((l_i,r_i,k_i)\),你

我们记 \(f_i\) 表示仅考虑需要求出有多少长度为 \(n\) 的序列 \(a_1,a_2,\cdots,a_n\) 满足以下条件:

  • \(\forall 1 \leq i \leq n,1 \leq a_i \leq s\)。
  • 对于第 \(i(1 \leq i \leq m)\) 个三元组,\(a_{l_i},a_{l_i + 1},\cdots,a_{r_i}\) 不全等于 \(k_i\)。

输出结果对 \(998244353\) 取模的结果。

\(1 \leq n,m,s \leq 2 \times 10^5\)。

首先可以考虑对于每种颜色拆开来做,对于一种颜色,如果一个区间包含了另一个区间,则大的区间可以舍去,容易证明。把限制挂在右端点。

我们记 \(f_i\) 表示只考虑 \(m\) 个限制中 \(r \leq i\) 的限制,在 \([1,i]\) 中填数的合法方案数,\(g_i\) 表示只考虑 \(r < i\) 的限制合法且只考虑 \(r \leq i\) 不合法的填数方案数。由于我们已经舍去了包含的方案,所以对于一个 \(i\) 只会有一个限制挂在这里,设这个限制为 \([l,i]\),那么有 \(g_i = f_{l - 1}\),但是这样会算重,若有一个区间 \([l1,r1]\) 满足 \(r1 \geq l\),那么 \([l1,i]\) 都填为当前做的元素会在 \(r1,i\) 都被算一次,于是正确的应该是 \(g_i = f_{l - 1} - \sum_{l \leq j < i} g_j\)。这个容易用二分 + 前缀和优化。

于是对于每种颜色算出他们各自的 \(g_i\) 把他们加在一起就是整体的 \(g_i\) 了,\(f_i = f_{i - 1} \times s - g_i\)。

答案即为 \(f_n\)。

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+5,p=998244353;
int n,m,s,f[N],g[N];
vector<int> id[N],sum[N];
vector<pair<int,int>> col[N],ve[N];
signed main() {
	cin>>n>>m>>s;
	for(int i=1; i<=m; i++) {
		int l,r,k;
		cin>>l>>r>>k;
		col[k].push_back(make_pair(l,r));
	}
	for(int i=1; i<=s; i++) {
		if(col[i].empty()) continue;
		sort(col[i].begin(),col[i].end(),[](pair<int,int> &a,pair<int,int> &b) {
			if(a.first==b.first) return a.second>b.second;
			else return a.first<b.first;
		});
		int mn=n+1;
		for(int j=col[i].size()-1; j>=0; j--) {
			if(col[i][j].second>=mn) continue;
			mn=col[i][j].second;
			ve[col[i][j].second].push_back(make_pair(col[i][j].first,i));
		}
	}
	f[0]=1;
	for(int i=1; i<=n; i++) {
		for(int j=0; j<ve[i].size(); j++) {
			int fi=ve[i][j].first,se=ve[i][j].second;
			int ans=f[fi-1];
			if(!id[se].empty()) {
				int pos=lower_bound(id[se].begin(),id[se].end(),fi)-id[se].begin()-1;
				ans=(ans-sum[se].back()+(pos>=0?sum[se][pos]:0)+p)%p;
			}
			id[se].push_back(i);
			if(!sum[se].empty()) sum[se].push_back((sum[se].back()+ans)%p);
			else sum[se].push_back(ans);
			g[i]=(g[i]+ans)%p;
		}
		f[i]=(f[i-1]*s%p-g[i]+p)%p;
	}
	cout<<f[n];
	return 0;
}

闲话:只输入 \(n\) 个数能拿 \(90\) /kx。

T4

原题:P5655。

会了。

感觉这篇讲的很好,有一点疑惑的地方,不过想想也能理解,就不做解释了。

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=305,mod=998244353;
int t,n,a[N],c[N],b[N],s[N];
signed main() {
	cin>>t;
	while(t--) {
		cin>>n;
		for(int i=1; i<=n; i++) cin>>a[i];
		int ans=0;
		for(int i=1; i<=n; i++) {
			b[i]=a[i];s[i]=1;
			for(int j=i-1; j>=1; j--) s[j]=(__int128)s[j+1]*(b[j]%a[i])%a[i];
			int tmp=__gcd(s[1],a[i]);
			for(int j=1; j<i; j++) {
				if(s[j+1]%tmp) {
					int t=__gcd(s[j+1],tmp);
					b[j]/=tmp/t;tmp=t;
				}
			}
			int mul=1;
			for(int j=i; j>=1; j--) {
				mul=mul*(b[j]%mod)%mod;
				ans=(ans+mul)%mod;
			}
		}
		cout<<ans<<endl;
	}
	return 0;
}

标签:noip,int,sum,long,leq,241114,ans,序列,模拟
From: https://www.cnblogs.com/System-Error/p/18546730

相关文章

  • [68] (炼石计划) NOIP 模拟赛 #20
    学了一个挺帅的MerMaid所以用一下MerMaid就是你们接下来会看到的好看小标题但是实际上它是用来画流程图的……flowchartTB A(邻间的骰子之舞) styleAcolor:#ffffff,fill:#00c0c0,stroke:#ffffff考虑每次复制以后一定会粘贴若干次(大于零,否则没有意义),因此将复制粘贴捆绑......
  • MX 2025--炼石计划 NOIP 模拟赛 #20
    打得抽象。T3,T4放俩难的板子。由于是MX的题,就不放题意了。邻间的骰子之舞发现复制操作不会超过\(64\)次,而粘贴操作肯定是越均匀越好,直接二分暴力跑就行了。点此查看代码#include<bits/stdc++.h>usingnamespacestd;#definerep(i,s,t,p)for(inti=s;i<=t;i+=p)#......
  • 【C++】STL--queue、deque、priority的模拟实现和应用
    目录1、queue的介绍1.2queue的常规操作 2、queue的模拟实现 3、priority_queue(优先级队列)的介绍和实现3.1priority_queue的使用 3.2 priority_queue的应用 3.3 priority_queue的模拟实现4、deque4.1deque的原理介绍4.2deque的缺陷4.3 为什么选择deque作......
  • 【考试题解】NOIP2024(欢乐)加赛3
    目录A.SakurakoandWater题目内容思路代码B.BinomialCoefficients,KindOf题目内容思路代码C.QED'sFavoritePermutation题目内容思路代码D.CardGame题目内容思路代码E.LongWaytobeNon-decreasing题目内容思路代码F.ManyGames题目内容思路代码A.SakurakoandW......
  • MX 炼石计划 NOIP 模拟赛20(我真做过1~19吗?)
    MX炼石计划NOIP模拟赛#20T1邻间的骰子之舞二分答案,发现性质,签到,过。记得开__int128没开,挂30.码:CODE#include<bits/stdc++.h>typedeflonglongll;usingnamespacestd;constintN=2e5+100;#ifdeflinux#definegetchargetchar_unlocked#define......
  • 2024.11.14 NOIP训练赛
    2024.11.14NOIP训练赛Problem对满足以下条件的01矩阵\(A\)计数:行数为\(n+1\)(从\(0\)至\(n\)标号),列数为\(k\)(从\(1\)至\(k\)标号);不存在使得\(A_{0,i}\simA_{n-1,i}\)这\(n\)个数都为\(1\)的列\(i\);存在使得\(A_{1,i}\simA_{n,i}\)这\(n\)......
  • 第十三:BurpSuite模拟器安装Burp Suite证书(一)-重点
    一.模拟器安装BurpSuite证书抓取安卓应用(使用协议为http/https的数据包)1.下载逍遥模拟器地址:https://www.xyaz.cn/2.注意:安装程序一直下一步注意:目录(文件夹)不要出现中文(防止出现错误,无法正常安装成功)!!!3.windows+R-cmd-config//查看本机ip地址4.为模拟器......
  • 终端ssh终端模拟软件:Termius激活安装包
    Termius是一款功能强大的跨平台终端管理工具,提供了友好的用户界面,支持SSH、Telnet、SFTP等多种连接协议,方便用户远程连接和管理服务器。此外,Termius还支持多平台同步、文件传输、批量操作、脚本自动化等进阶功能,且具备强大的数据加密和安全性保障。无论是开发人员、系统管理员还......
  • NOIP2024模拟赛27 | 选手只有 T4 AC
    又是高一rk7。这场大众分太高了。我以为有很多人过T4的。80(95)+80+45(55)+100,sy机子太慢了。T1:场上只想出来\(A^{1/4}\log^2A\)的单次做法,只有80。即枚举小的那个底数。结论:满足条件的数可以表示成\(a^2b^3\)。???这样直接枚举\(\min(a,b)\le4000\)的质因子就做......
  • 【Unity人群寻路插件】CrowdPath Pathfinding 高效的路径规划算法来模拟群体寻路行为,
    CrowdPathPathfinding是一款专为Unity设计的路径寻找插件,主要用于处理复杂的人群导航问题,特别适合需要大规模虚拟人物群体移动的游戏或应用。它通过高效的路径规划算法来模拟群体行为,如避开障碍、避免拥挤、相互避让等。主要特点:高效的人群路径寻找:插件能够在复杂环境......