首页 > 其他分享 >P10888 【MX-S3-T4】「FeOI Round 1」醒餞の鳥 (feat. Feryquitous) 题解

P10888 【MX-S3-T4】「FeOI Round 1」醒餞の鳥 (feat. Feryquitous) 题解

时间:2024-08-17 19:49:41浏览次数:9  
标签:ch mxz S3 题解 醒餞 times int mod 科目

话说这题真的有紫吗(问号

注意到数据范围中提到 $\sum{nm} \le 2 \times 10^5 $,这里实际上是隐含了 \(\min(n,m) \le \sqrt{2\times 10^5}\) 的。我们考虑根据 \(n\) 和 \(m\) 的大小关系设计出不同的算法。

  • \(m<n\)

一个比较直接的想法是对于每一个科目先按该科目的分数排序,这样我们只需要考虑相邻两个人的关系即可。

对于排名相邻的两种分数的人,最坏情况下的赋值一定是把剩下的权值全部给后面一名的优势科目,若枚举到第 \(j\) 个科目,第 \(i\) 个人,后面的人超出前面的人最多分数的科目为 \(k\) 的话,那么 \(p_k\) 需满足:

\[p_j \times (a_{i,j} - a_{i-1,j}) > (1-p_j) \times (a_{i-1,k} - a_{i,k}) \]

直接计算,最后取最大值即可。时间复杂度 \(O(nm^2)\)。

  • \(n<m\)

和上一种情况类似,但这一次我们要尽量避免枚举 \(m\)。

双层循环枚举学生 \(i\) 和 \(j\),遍历每一科目,先找到 \(j\) 相对 \(i\) 的优势科目,再对任意 \(k\) 使得 \(c_{i,k} > c_{j,k}\) (即 \(i\) 的排名比 \(j\) 高)计算贡献即可。

时间复杂度 \(O(n^2m)\)。

代码
#include<bits/stdc++.h>
using namespace std;
inline void rd(){}
template<typename T,typename ...U>
inline void rd(T &x,U &...args){
	char ch=getchar();
	T f=1;x=0;
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
	x*=f;rd(args...);
}
const int N=1e5+5,mod=998244353;
int T,n,m;
struct node{vector<int> v;}a[N],tmp[N],tmp2[N];
inline int KSM(int x,int n){
	int ans=1;
	while(n){
		if(n&1)ans=1ll*x*ans%mod;
		x=1ll*x*x%mod;
		n>>=1;
	}
	return ans;
}
namespace m2n{
	inline void Solve(){
		for(int j=0;j<m;j++){
			int mxm=1,mxz=0,cnt=0;
			sort(a+1,a+n+1,[=](node a,node b){return a.v[j]<b.v[j];});
			tmp[++cnt]=a[1];tmp2[cnt]=a[1];
			for(int i=2;i<=n;i++){
				if(a[i].v[j]!=a[i-1].v[j])tmp[++cnt]=a[i],tmp2[cnt]=a[i];
				else {
					for(int k=0;k<m;k++)
						tmp[cnt].v[k]=min(tmp[cnt].v[k],a[i].v[k]),
						tmp2[cnt].v[k]=max(tmp2[cnt].v[k],a[i].v[k]);
				}
			}
			for(int i=2;i<=cnt;i++){
				int c1=tmp[i].v[j]-tmp[i-1].v[j],c2=0;
				for(int k=0;k<m;k++){
					if(k==j)continue;
					c2=max(c2,tmp2[i-1].v[k]-tmp[i].v[k]);
				}
				if(!c2)continue;
				if(1ll*c2*mxm>1ll*(c1+c2)*mxz)mxm=c1+c2,mxz=c2;
			}
			printf("%lld\n",1ll*mxz*KSM(mxm,mod-2)%mod);
		}
		for(int i=1;i<=n;i++)a[i].v.clear();
	}
}
namespace n2m{
	int mxz[N],mxm[N];
	inline void Solve(){
		for(int i=0;i<=m;i++)mxz[i]=0,mxm[i]=1;
		for(int x=1;x<=n;x++){
			for(int y=1;y<=n;y++){
				if(x==y)continue;
				int c2=0;
				for(int i=0;i<m;i++)
					c2=max(c2,a[y].v[i]-a[x].v[i]);
				for(int i=0;i<m;i++){
					if(a[y].v[i]>=a[x].v[i])continue;
					int c1=a[x].v[i]-a[y].v[i];
					if(a[x].v[i]>a[y].v[i])
						if(1ll*(c1+c2)*mxz[i]<1ll*mxm[i]*c2)mxm[i]=c1+c2,mxz[i]=c2;
				}
			}
		}
		for(int i=0;i<m;i++)
			printf("%lld\n",1ll*mxz[i]*KSM(mxm[i],mod-2)%mod);
		for(int i=1;i<=n;i++)a[i].v.clear();
	}
}
signed main(){
	rd(T);
	while(T--){
		rd(n,m);
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				int x;rd(x);
				a[i].v.push_back(x);
			}
		}
		if(n<=m)n2m::Solve();
		else m2n::Solve();
	}
	return 0;
}

标签:ch,mxz,S3,题解,醒餞,times,int,mod,科目
From: https://www.cnblogs.com/11-twentythree/p/18364882

相关文章

  • 【MX-S3】梦熊周赛 · 提高组 3 & FeOI Round 1
    野心Journey题意:\(\text{range}(a,b,c)\)表示序列\[[a,a+c,a+2c,\cdots,a+kc]\]其中\(k\)是满足\(a+kc<b\)的最大非负整数。给定大小为\(n\le2\times10^7\)的数组\(g\),求\[\sum_{a=1}^n\sum_{b=a+1}^n\sum_{c=1}^n\sum_{i\in\tex......
  • 在相思树下 III 题解
    前言题目链接:洛谷。赛时脑子坨成一坨了,估计是T1的影响,写一篇题解来理清思路。题意简述给你一个长为\(n\)的序列\(a_{1\dotsn}\),你需要对它进行两种操作共\(n-1\)次。对一个长度为\(l\)的序列\(b_{1\dotsl}\)进行一次操作将会把序列变为一个长为\(l-1\)的序列......
  • n1gr tS0i 题解
    前言题目链接:洛谷。想了一个小时,想到后只用\(1\)分钟过了的题。官方题解过于晦涩,看到一篇很清晰的题解,于是写题解以记之。终于遇到时间瓶颈在输入的题目。题意简述有一个长度为\(n\)的\(\tt01\)串\(S\),你要对\(S\)进行恰好\(n\)次操作。每次操作选择\(1\leq......
  • 洛谷 B3735 B3736 B3787 题解
    嘿嘿我发烧已经好了!题目目录:No.1 B3735[信息与未来2018]圣诞树No.2 B3736[信息与未来2018]最大公约数No.3 B3787[信息与未来2023]精密计时 OK,开始正文!第一题:B3735[信息与未来2018]圣诞树 题目描述圣诞树共有 nn 层,从上向下数第 11 层有 11 个......
  • 题解:AT_arc181_b [ARC181B] Annoying String Problem
    思路首先我们可以根据两个字符串算出另外一个字符串\(T\)的长度。算出来之后,因为我们要满足等式两边完全相等,所以很容易得出这两个字符串应该都是由一些公共的字串拼接而成的。设\(S\)串中最小的周期为\(P\)。所以应该满足\(|P|\Large{\mid}\normalsize\gcd(|S|,|T|)\)......
  • 题解:AT_arc182_a [ARC182A] Chmax Rush!
    思路因为前面不允许出现比这次的替换的值还要大的情况,所以如果我们知道下标\(i,j\)满足\(i<j\)且\(V_i>V_j\)的话,我们就必须把它们两次修改分开。具体地:若\(P_i<P_j\):此时,我们只能将\([1,P_i]\)的值设为\(V_i\),将\([P_j,n]\)的值设为\(V_j\)。若\(P_i>P_j\):此......
  • P8735 蓝跳跳 题解
    Statement给出\(k,p,L\),数序列\(a\),满足如下条件:\(1\lea_i\lek\)\(\sum_ia_i=L\)\(\nexistsi,a_i\gep\landa_{i+1}\gep\)答案对\(20201114\)取模,\(p\lek\le1000,L\le10^{18}\).Solution30pts注意到可以dp,记\(f(i,0/1)\)为凑出\(i\)的方案......
  • INFS3208 – Cloud Computing
    SchoolofElectricalEngineeringandComputerScienceINFS3208–CloudComputingProgrammingAssignmentTaskI(10Marks)Taskdescription:Youareadeveloperataleadingsoftwaredevelopmentcompanytaskedwithcreatingascalableandefficientdeploy......
  • 信息学奥赛一本通编程启蒙题解(3011~3015)
    前言Hello大家好,我是文宇.正文3011#include<iostream>usingnamespacestd;intmain(){ inta,b,s; a=880; b=500; s=a*b; cout<<s; return0;}注:没有输入的都可以直接输出.3012#include<iostream>usingnamespacestd;inta,b,t;intmain(){ a=10;b=20......
  • 信息学奥赛一本通编程启蒙题解(3021~3025)
    前言hello大家好,我是文宇。正文3021#include<iostream>usingnamespacestd;inta,b,c,d;intmain(){ cin>>a>>b>>c>>d; cout<<a+b+c+d; return0;}3022#include<bits/stdc++.h>usingnamespacestd;intmain(){ inta,b,c; ......