当前位置: 首页 > news >正文

25.2.25补题

2.25abc补题

abc391F K-th Largest Triplet

题意

给定三个长度为 n n n的整数数组 A , B , C A,B,C A,B,C,以及一个整数 K K K,对于整数 i , j , k ( 1 ≤ i , j , k ≤ n ) i,j,k (1 \leq i, j,k \leq n) i,j,k(1i,j,kn)的每一个 N 3 N^3 N3选项,计算 A i ∗ B j + A i ∗ C k + b j ∗ C k A_i*B_j+A_i*C_k+b_j*C_k AiBj+AiCk+bjCk的值,并输出第 K K K大的值

思路

  • 先将 A , B , C A,B,C A,B,C数组降序排列后,第一大的下标肯定是 [ 1 , 1 , 1 ] [1,1,1] [1,1,1]
  • 则第二大的下标一定为 [ 2 , 1 , 1 ] , [ 1 , 2 , 2 ] , [ 1 , 1 , 2 ] [2,1,1],[1,2,2],[1,1,2] [2,1,1],[1,2,2],[1,1,2]其中之一,由此可知每个确定的最大值可以推出三个次大值,接下来的最大值就在三个次大值之中产生
  • 可以使用优先队列维护每个最大值,再将其推出的三个次大值不断丢进去
  • 为避免重复,使用set维护已经得到过的下标

代码

#include<bits/stdc++.h>

#define ull unsigned long long 
#define ll long long
#define inf 0x3f3f3f3f
#define lc p<<1
#define rc p<<1|1
#define endl '\n'
#define all(a) a.begin()+1,a.end()
#define all0(a) a.begin(),a.end()
#define lowbit(a) (a&-a)
#define fi first
#define se second
#define pb push_back
#define yes cout<<"YES"<<endl
#define no cout<<"NO"<<endl

using namespace std;
const double eps=1e-6;
typedef pair<int,int>PII;
typedef array<int,3>PIII;
mt19937_64 rnd(time(0));  



void solve()
{
	int n,k;
	cin>>n>>k;
	vector<ll>a(n+1);
	auto b=a;
	auto c=a;
	
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<=n;i++) cin>>b[i];
	for(int i=1;i<=n;i++) cin>>c[i];
	
	sort(all(a),greater<ll>());
	sort(all(b),greater<ll>());
	sort(all(c),greater<ll>());
	
	set<PIII>s;
	priority_queue<pair<ll,PIII>>q;
	q.push({a[1]*b[1]+a[1]*c[1]+b[1]*c[1],{1,1,1}});
	s.insert({1,1,1});
	
	while(k>1)
	{
		auto [x,y]=q.top();
		q.pop();
		//cout<<x<<endl;
		k--;
		
		if(y[0]<n && s.find({y[0]+1,y[1],y[2]})==s.end())
		{
			q.push({a[y[0]+1]*b[y[1]]+a[y[0]+1]*c[y[2]]+b[y[1]]*c[y[2]],{y[0]+1,y[1],y[2]}});
			s.insert({y[0]+1,y[1],y[2]});
		}
		
		if(y[1]<n && s.find({y[0],y[1]+1,y[2]})==s.end())
		{
			q.push({a[y[0]]*b[y[1]+1]+a[y[0]]*c[y[2]]+b[y[1]+1]*c[y[2]],{y[0],y[1]+1,y[2]}});
			s.insert({y[0],y[1]+1,y[2]});
		}
		
		if(y[2]<n && s.find({y[0],y[1],y[2]+1})==s.end())
		{
			q.push({a[y[0]]*b[y[1]]+a[y[0]]*c[y[2]+1]+b[y[1]]*c[y[2]+1],{y[0],y[1],y[2]+1}});
			s.insert({y[0],y[1],y[2]+1});
		}
	}
	cout<<q.top().fi<<endl;
}
	
	
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	
	solve();
	
	return 0;
}

abc390 D-Stone XOR

题意

n 个袋子 ( 2 ≤ n ≤ 12 ) n个袋子(2 \leq n \leq 12) n个袋子(2n12),每个袋子有若干石头,每次操作可以将一个袋子中的石头全部放到另一个袋子中,问执行若干次操作之后(可能为0次),所有袋子中石头的数量的异或之和有多少种可能的结果

思路

  • 等价于最多有12个元素,要把他们拆分到任意个数的集合之中,问这些集合的元素的异或和有多少种不同的取值

  • 很经典的集合拆分问题,用 B ( n ) B(n) B(n)表示把 n n n个元素拆分的方案数,其中 B ( 12 ) ≈ 4 e 6 B(12) \approx 4e6 B(12)4e6,所以可以dfs枚举所有情况

  • dfs我们需要维护三个值
    1.当前选择到了第几个袋子
    2.当前每个集合中的石子数量
    3.当前划分的集合数量

  • 对于每个新考虑的元素,我们有两种策略
    1.将其加入已经划分的某个集合之中
    2.将其放入新集合之中

代码

// Problem: D - Stone XOR
// Contest: AtCoder - AtCoder Beginner Contest 390
// URL: https://atcoder.jp/contests/abc390/tasks/abc390_d
// Memory Limit: 1024 MB
// Time Limit: 3000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>

#define ull unsigned long long 
#define ll long long
#define inf 0x3f3f3f3f
#define lc p<<1
#define rc p<<1|1
#define endl '\n'
#define all(a) a.begin()+1,a.end()
#define all0(a) a.begin(),a.end()
#define lowbit(a) (a&-a)
#define fi first
#define se second
#define pb push_back
#define yes cout<<"YES"<<endl
#define no cout<<"NO"<<endl

using namespace std;
const double eps=1e-6;
typedef pair<int,int>PII;
typedef array<int,3>PIII;
mt19937_64 rnd(time(0));  



void solve()
{
	int n;cin>>n;
	vector<ll>a(n+1);
	for(int i=1;i<=n;i++) cin>>a[i];
	
	unordered_set<ll>s;
	vector<ll>ss(n);//集合
	
	auto dfs=[&](auto && dfs,int id,vector<ll>&cur,int used)->void
	{
		if(id==n+1)
		{
			ll ans=0;
			for(auto x:cur) ans^=x;
			//cout<<ans<<endl;
			//for(auto x:cur) cout<<x<<" ";
			//cout<<endl;
			s.insert(ans);
			return;
		}
		//将当前石子加入已有集合
		for(int i=0;i<used;i++)//枚举加入的集合
		{
			ll last=cur[i];
			cur[i]+=a[id];
			dfs(dfs,id+1,cur,used);
			cur[i]=last;
		}
		//将当前石子放到新集合
		if(used<n)
		{
			cur[used]=a[id];
		    dfs(dfs,id+1,cur,used+1);
		    cur[used]=0;
		}
		
	};
	
	dfs(dfs,1,ss,0);
	cout<<s.size()<<endl;
	//for(auto t:s) cout<<t<<endl;
}
	
	
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	
	solve();
	
	return 0;
}

相关文章:

  • freetype封装
  • Java进阶学习笔记95——网络编程
  • langchain系列(五)- LangChain 的tool原理与代码实现
  • SpringSecurity获取当前登录用户信息
  • AI提示词的种类与适合的任务
  • DeepSeek开源周 Day02:从DeepEP开源趋势重新审视大模型Infra
  • WordPress Course Booking System SQL注入漏洞复现 (CVE-2025-22785)(附脚本)
  • 1分钟用DeepSeek编写一个PDF转Word软件
  • springboot志同道合交友网站设计与实现(代码+数据库+LW)
  • HTTP/HTTPS 服务端口监测的简易实现
  • 鸿蒙5.0实战案例:har和hsp的转换
  • 三、大模型微调的多种方法与应用场景
  • 搜索优化:微调模型与RAG技术的深度比较
  • 适配 AGP8.5 版本,各种问题(三)
  • vue3.0将后端返回的word文件流转换为pdf并导出+html2pdf.js将页面导出为pdf
  • C#快速调用DeepSeek接口,winform接入DeepSeek查询资料 C#零门槛接入DeepSeek C#接入DeepSeek源代码下载
  • self-attention部分代码注释
  • Pi-hole v6释出
  • android系统 使用哪些工具可以分析组件间的依赖
  • Dubbo RPC 原理
  • 日照网站网站建设/成人职业培训学校
  • dw怎样做网站切换/网站运营管理
  • 池州做网站的公司/网络推广营销公司
  • 网站建设地位/站长统计幸福宝2022年排行榜
  • wordpress插件/长沙seo男团
  • 常州做网站的/系统优化助手