多校联测11 THUSC

题目大意

nnn个人参加THUSCTHUSCTHUSC,第iii个人算法场和工程场的成绩分别为aia_iaibib_ibi,保证不存在两个人两项成绩都相同。

现在招办想给他们排个名。一个合理的排名方案是分别给算法场和工程场一个正的权重x,yx,yx,y,然后按照aix+biya_ix+b_iyaix+biy降序排名,相同的可以按照他们的心情排。

对于一个成绩分布,求有多少种可能的排名。

输出答案对998244353998244353998244353取模后的值。

1≤n≤1000,1≤ai,bi≤1091\leq n\leq 1000,1\leq a_i,b_i\leq 10^91n1000,1ai,bi109


题解

因为当x1≠x2,y1≠y2x_1\neq x_2,y_1\neq y_2x1=x2,y1=y2x1y1=x2y2\dfrac{x_1}{y_1}=\dfrac{x_2}{y_2}y1x1=y2x2时,权重为x1,y1x_1,y_1x1,y1x2,y2x_2,y_2x2,y2所得的排名是相同的。所以,我们只需考虑比值xy\dfrac xyyx,令比值为w=xyw=\dfrac xyw=yx

首先,我们把所有满足题意的www分成两个类型:

  • 能使有至少两个人分数一样
  • 能使任意两个人的分数不一样

因为存在分数一样的时候分数相同的任意排,所以所有第二种类型的www所得的排名都一定会在第一种类型的www所得的排名中出现。(可以自己举几个例子试一下)。

那么,我们只需要求能使至少两个人分数一样的www即可,而能使至少两个人分数一样的www不超过n2n^2n2个(对于任意两对ai,bia_i,b_iai,bi,只有一个www满足两者排名相同)。

枚举两个人i,ji,ji,j,求出能使i,ji,ji,j两个人分数相等的www。然后,我们只需考虑在每个不同的www作为比值的情况下有多少种排名即可。

这怎么处理呢?我们在求出能使i,ji,ji,j两个人分数相等的www的时候,在图上将i,ji,ji,j两点连一条权值为www的双向边,再从虚拟节点n+1n+1n+1iii连一条权值为www的单向边。等到全部边都连完了之后,对于每一个不同的www,看虚拟节点有多少个权值为www的边连出去。对于每个从虚拟节点指向的点iii,看从iii经过权值为www的边能够到达多少个点(包括自己),这些点当前的分数是与iii的分数相同的。若能够到达ttt个点,则贡献为t!t!t!。换句话说,设vwv_wvw表示比值为www时不同排名的数量,则当得知iii能到达ttt个点时,vw=vw×t!v_w=v_w\times t!vw=vw×t!

在处理边的时候,我们可以将每个点连出的边按边权从小到大排序,那么走过的边就不用再走了,能保证每条边只会被遍历一次。

因为相邻的两个能使两人分数相等的www之间的那种排名会被计算两次,所以要减去,那么答案为1+∑(vw−1)1+\sum (v_w-1)1+(vw1)

枚举i,ji,ji,j的时间复杂度为O(n2)O(n^2)O(n2),排序的时间复杂度为O(n2log⁡n)O(n^2\log n)O(n2logn)。总共有不超过3n23n^23n2条边,每条边最多遍历一次,所以图上部分的时间复杂度为O(n2)O(n^2)O(n2)。所以,总时间复杂度为O(n2log⁡n)O(n^2\log n)O(n2logn)

code

#include<bits/stdc++.h>
using namespace std;
const long long mod=998244353;
const int N=3000000;
int n,w1=0,now,z[N+5],to[1005];
long long ans=0,nd,a[1005],b[1005],jc[1005];
struct node{
	int a,b;
	long long x,y;
	bool operator==(const node ax)const{
		return x==ax.x&&y==ax.y;
	}
	bool operator!=(const node ax)const{
		return x!=ax.x||y!=ax.y;
	}
}w[1000005];
struct pr{
	int x,v;
};
vector<pr>g[1005];
bool cmp(node ax,node bx){
	if(ax.x!=bx.x) return ax.x<bx.x;
	return ax.y<bx.y;
}
long long gcd(long long i,long long j){
	while(j){
		i%=j;swap(i,j);
	}
	return i;
}
void dfs(int u,int t){
	if(z[u]==t) return;
	z[u]=t;
	++now;
	for(int i=to[u];i<g[u].size();++i,++to[u]){
		if(w[g[u][i].v]!=w[t]) break;
		dfs(g[u][i].x,t);
	}
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld%lld",&a[i],&b[i]);
	}
	jc[0]=1;
	for(int i=1;i<=1000;i++) jc[i]=jc[i-1]*i%mod;
	for(int i=1;i<=n;i++){
		for(int j=i+1;j<=n;j++){
			long long x=b[i]-b[j],y=a[j]-a[i],d;
			if(x*y<0) continue;
			if(x==0||y==0) continue;
			if(x<0){
				x=-x;y=-y;
			}
			d=gcd(x,y);
			x/=d;y/=d;
			w[++w1]=(node){i,j,x,y};
		}
	}
	sort(w+1,w+w1+1,cmp);
	for(int i=1;i<=w1;i++){
		g[w[i].a].push_back((pr){w[i].b,i});
		g[w[i].b].push_back((pr){w[i].a,i});
		g[n+1].push_back((pr){w[i].a,i});
	}
	for(int i=1;i<=w1;i++){
		if(i>1&&w[i]==w[i-1]) continue;
		nd=1;
		for(int j=to[n+1];j<g[n+1].size();++j,++to[n+1]){
			if(w[g[n+1][j].v]!=w[i]) break;
			now=0;
			dfs(g[n+1][j].x,i);
			nd=nd*jc[now]%mod;
		}
		ans=(ans+nd)%mod;
		ans=(ans-1+mod)%mod;
	}
	ans=(ans+1)%mod;
	printf("%lld",ans);
	return 0;
}
### 产品联合测试流程和注意事项 产品联合测试(简称“联测”)是软件开发过程中一个关键环节,特别是在个团队或模块协同开发的场景中。其主要目的是验证不同模块、系统或服务之间的接口是否能够正确交互,确保整体功能的完整性和稳定性。 #### 联测流程 1. **需求对齐与测试计划制定** 在联测开始前,各方需对产品需求、功能边界、接口规范进行明确,并制定详细的测试计划,包括测试范围、测试用例设计、测试环境准备、测试时间安排等。 2. **接口文档准备与评审** 各方需提供完整的接口文档,包括请求方式、参数说明、返回值格式、错误码定义等。通过文档评审确保接口设计合理且无歧义。 3. **测试环境搭建与接口联调** 搭建与生产环境尽可能一致的测试环境,进行接口联调。此阶段主要验证接口是否能正常通信,响应是否符合预期。 4. **执行测试用例与缺陷管理** 根据测试计划执行测试用例,记录测试结果。发现缺陷后需及时提交并跟踪修复情况,确保问闭环。 5. **回归测试与验收确认** 缺陷修复后进行回归测试,验证问是否彻底解决。最终由相关方确认测试结果,完成联测交付。 6. **联测总结与文档归档** 联测结束后进行总结,分析测试过程中的问与经验,归档测试文档,为后续维护和升级提供依据。 #### 注意事项 - **接口一致性** 确保接口在开发与测试阶段保持一致性,避免因接口变更导致测试失败。如有变更,应及时同步文档并通知相关方。 - **数据隔离与安全性** 测试数据应与生产数据隔离,防止测试行为影响真实业务。同时需注意敏感数据的脱敏处理。 - **异常处理与容错机制** 需对接口异常情况进行测试,如超时、参数错误、服务不可用等,确保系统具备良好的容错能力。 - **日志与监控** 联测过程中应开启详细的日志记录,便于问定位。建议引入监控工具,实时观察接口调用状态与性能。 - **沟通与协作机制** 联测涉及方协作,需建立高效的沟通机制,及时处理测试中发现的问,避免因沟通不畅影响进度。 - **自动化测试支持** 建议在联测阶段引入自动化测试工具,提升测试效率与覆盖率,尤其适用于回归测试。 #### 示例:接口联测测试用例(伪代码) ```python def test_api_response(): # 请求参数 payload = { "user_id": 12345, "token": "abc123xyz" } # 发起请求 response = api_client.post("/user/profile", data=payload) # 验证响应状态码 assert response.status_code == 200 # 验证返回数据结构 assert "username" in response.json() assert "email" in response.json() # 验证错误处理 invalid_payload = {"user_id": None} error_response = api_client.post("/user/profile", data=invalid_payload) assert error_response.status_code == 400 ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值