首页 > 其他分享 >2022.9.26比赛记录

2022.9.26比赛记录

时间:2022-09-26 16:55:44浏览次数:51  
标签:26 ch 比赛 limits int sum long 2022.9 define

T1

题意

给定两个长度为 \(n\) 的序列 \(a,b\),选择一个最长的区间 \([l,r]\) 使得 \(\sum\limits_{i=l}^r a_i \ge 0\) 并且\(\sum\limits_{i=l}^r b_i \ge 0\)。

输出这个区间的长度。

思路

我们记 \(s_i = \sum\limits_{j=1}^i a_j,t_i = \sum\limits_{j=1}^i b_j\)。

题目的条件即可转换为 \(s_r - s_{l-1} \ge 0\) 并且 \(t_r - t_{l-1} \ge 0\)。

不难想到,我们可以将 \(s\) 升序排序,这样我们就只需要考虑 \(t_r - t_{l-1} \ge 0\) 这个限制,直接树状数组维护即可。

复杂度是单 \(log\) 的。

代码

click
#include<bits/stdc++.h>
#define ll long long
#define int long long
#define vi vector<int>
#define pii pair<int,int>
#define pb(x) push_back(x)
#define lowbit(x) x&-x
using namespace std;
const int N=5e5+10;
struct node{
	int a,b,id;
}a[N];
ll ans;
int n,m,T,c[N],d[N];
inline int read(){
	int s=0,f=0;
	char ch=getchar();
	while(ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
	while(ch<='9'&&ch>='0') s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
	return f?-s:s;
}
inline void add(int x,int c){
	for(;x<=N;x+=lowbit(x)) d[x]=min(c,d[x]);
}
inline int sum(int x){
	int res=1e18;
	for(;x;x-=lowbit(x)) res=min(d[x],res);
	return res;
}
inline bool cmp(node a,node b){
	return a.a==b.a?a.b<b.b:a.a<b.a;
}
signed main(){
	n=read();
	for(register int i=0;i<N;++i)  d[i]=1e9;
	for(register int i=1;i<=n;++i) a[i].a=read(),a[i].a+=a[i-1].a;
	for(register int i=1;i<=n;++i) a[i].b=read(),a[i].b+=a[i-1].b;
	for(register int i=1;i<=n;++i) c[i]=a[i].b,a[i].id=i;
	sort(c+1,c+n+1);
	sort(a+1,a+n+1,cmp);
	int tot=unique(c+1,c+n+1)-c-1;
	for(register int i=1;i<=n;++i) a[i].b=lower_bound(c+1,c+tot+1,a[i].b)-c;
	for(register int i=1;i<=n;++i){
		ans=max(ans,a[i].id-sum(a[i].b));
		add(a[i].b,a[i].id);
	}
	cout<<ans;
	return 0;
}

T2

题意

给定 \(n\) 个二元组 \((a_i,b_i)\),你可以选出任意个并且将它们任意排列,要求 \(\forall i,a_i \leq b_j\) 其中 \(j>i\)。

问最多选出多少个。

思路

不妨先选出一些下标 \(p\),记为 \(p_1,p_2,\dots,p_n\),这些二元组构成的序列是合法的。

然后我们考虑怎么加入 \(p_i\) 到 \(p_{i+1}\) 之间的二元组。

假设该二元组为 \((a_q,b_q)\)。

发现一定不能插在 \(p_i\) 和 \(p_{i+1}\) 之间,但是可以插在 \(p_{i+1}\) 之后,思考一下发现这就是最优情况。

然后就可以开始 \(\text{dp}\) 了。

我们设 \(dp_{i}\) 表示取到第 \(i\) 个你所能得到的最大权值。

根据刚才的贪心方法,可以得到:

\(dp_i =\max\limits_{j <i 且 b_i \ge a_j}\{ {f_j + \sum\limits_{i < k < j 且 b_k \leq a_i} w_k}\} + w_i\)。

看起来很不可做。

但是我们发现,每个 \(\sum\) 条件中的第二个约束都是一个连续的区间,可以认为,\(\forall k\) 都只对一个连续的 \(i\) 的区间产生贡献,我们只需要在开始和结束的时候加/减去 \(k\) 的贡献即可。

使用线段树维护,时间复杂度 \(O(n\log n)\)。

代码

click
别急

T3

题意

给定 \(n\) 个点,每个点有一个权值 \(v_i\)。

你要构建一颗二叉查找树使得 \(\sum\limits_{i=1}^n d_i \times v_i\) 的值最小,其中 \(d_i\) 为第 \(i\) 个点在树中的深度。

思路

显然的,一颗子树的编号在序列中一定是一个连续的区间,然后直接区间 \(\text{dp}\)。

记 \(s_{l,r} = \sum\limits_{i=l}^r v_i\)。

写出暴力的转移式:\(f_{l,r} = \max\limits_{k=l}^r \{ f_{l,k-1} + f_{k+1,r} \} + s_{l,r}\)。

上帝告诉你这个式子符合四边形不等式的性质。

你记录 \(p_{l,r}\) 是 \(f_{l,r}\) 的最优决策点。

记 \(x = p_{l+1,r},y = p_{l,r-1}\) 。

你的枚举范围就变成了 \(\max\limits_{k=x}^{y}\)。

它的复杂度是 \(\sum\limits_{l \leq r} (p_{l,r-1} - p_{l+1,r}) = \sum\limits_{l \leq n} p_{l,n}- \sum\limits_{r \ge 1} p_{1,r} = O(n)\)。

所以总复杂度就是 \(O(n^2)\)。

代码

点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define int long long
#define vi vector<int>
#define pii pair<int,int>
#define pb(x) push_back(x)
#define lowbit(x) x&-x
using namespace std;
const int N=5e3+10;
ll ans;
int n,m,T,dp[N][N],p[N][N],a[N],sum[N];
inline int read(){
	int s=0,f=0;
	char ch=getchar();
	while(ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
	while(ch<='9'&&ch>='0') s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
	return f?-s:s;
}
signed main(){
	n=read();
	for(register int i=1;i<=n;++i) a[i]=read();
	for(register int i=1;i<=n;++i) sum[i]=a[i]+sum[i-1];
	for(register int i=1;i<=n;++i) dp[i][i]=a[i];
	for(register int i=1;i<=n;++i) p[i][i]=i;
	for(register int i=1;i<=n+1;++i) dp[i][i-1]=0;
	for(register int len=2;len<=n;++len){
		for(register int i=1;i+len-1<=n;++i){
			int j=i+len-1;
			for(register int k=p[i][j-1];k<=p[i+1][j];++k){
				if(dp[i][k-1]+dp[k+1][j]<=dp[i][j]){
					dp[i][j]=dp[i][k-1]+dp[k+1][j];
					p[i][j]=k;
				}
			}
			dp[i][j]+=sum[j]-sum[i-1];
		}
	}
	cout<<dp[1][n];
	return 0;
}

标签:26,ch,比赛,limits,int,sum,long,2022.9,define
From: https://www.cnblogs.com/kqwlp/p/16731515.html

相关文章

  • 9.26
    今日内容1.基本数据类型2.与用户交互3.格式化输出4.基本运算符5.常用赋值符6.逻辑运算符7.成员运算符8.身份运算符基本数据类型整型就是整数int代码实现:age......
  • 9月26日~10月2日
    9月26关于今天做了两道IOI的题,早些年的T1有些水……(虽然我做了IOI的题,但我却去不了IOI的赛场,艹好真实)。明白什么叫一步步来么......
  • 我的收藏周刊026
    文章分享“我觉得他们找错了靶子”许知远的《十三邀》之辩南方周末关于许知远十三邀的一篇文章,付费内容,值得一看。为什么需要虚拟化kernelnewbies上的以前为什么......
  • 闲话 22.9.26
    闲话调全体T4六点改出来了,但大样例不认为我改出来了于是又花了两个小时修改不存在的错误最近在做这题[JRKSJR4]risrqnis想做主要是因为上琴糖但是做着做着发现很......
  • 错过了一个比较大的编程比赛
    每天要积极乐观,不要再逼着自己去看言情小说,真的不喜欢,娱乐时间是要做让自己放松的事情的,不要再去想爱情,我绝对是不喜欢像唐伯虎那样的多情的人的,这一生能做好一件事对......
  • Value error: 'ascii' codec can't decode byte 0xe6 in position 26: ordinal not in
    原因:工作空间中有中文编码问题,导致的运行ros异常解决办法:1、解决urdf生成异常问题urdf文件中不允许有中文,所有当输入中文的时候容易出问题,解决方案:①在根目录下:/opt/ro......
  • 2022-2023-1 20221326《计算机基础与程序设计》第四周学习总结
    班级链接:https://edu.cnblogs.com/campus/besti/2022-2023-1-CFAP作业要求:https://www.cnblogs.com/rocedu/p/9577842.html#WEEK04作业目标:门电路组合电路,逻辑电路冯诺依......
  • 2022.9.24 总结
    B\(A\)\(B\)轮流行动,\(A\)需要拿走若干个数(不可不拿),\(B\)可以拿走一个数。\(A\)拿走的数和要最大,\(B\)则希望\(A\)拿走的数和最小。问\(A\)能拿走多少数的和......
  • sqlalchemy.exc.OperationalError: (MySQLdb._exceptions.OperationalError) (2026, '
    sqlalchemy.exc.OperationalError:(MySQLdb._exceptions.OperationalError)(2026,'SSLconnectionerror:unknownerrornumber')问题:使用sqlalchemy查询mysql数据时......
  • SOJ1626 方珍 题解
    传送门题意给定一个\(n×n\)的方阵,其中第\(i\)行为\(A_{i,1},A_{i,2},...,A_{i,n}\)。对于\(A_i\)的所有区间,设\(f_i\)为其中第\(k_i\)大的\(mex\)值。给......