首页 > 其他分享 >CF639E - Bear and Paradox | 二分答案 思维

CF639E - Bear and Paradox | 二分答案 思维

时间:2024-03-19 19:57:18浏览次数:39  
标签:Paradox int double eps Bear Dt include Mx CF639E

links
题目大意

自己可以想出来个七七八八,但很多地方没有把细节处理好,思考问题不全面,然后就花了很长时间……

显然答案具有单调性,直接二分答案。

对于一个二分的答案 \(c\) ,思考如何找到最优的做题顺序,考虑相邻的两道题,把他们的顺序调换,看最终的得分会如何变化。因为把这两道题调换,不会影响其他题的得分,所以得分的变化值是很好算的。一通分析之后,我们发现把 \(\frac{p_i}{t_i}\) 大的排在前面,可以使得答案最优。

到这里似乎就大功告成了,只需对于每个 \(c\) 都按这个顺序算一遍,然后看看内部有没有 paradox 就好了。但是这个题折磨的地方才刚刚开始。

按这个思路写一遍,一测第二个样例,欸,你猜怎么着,错了!哈哈哈

原来没有考虑 \(\frac{p_i}{t_i}\) 相同的情况,因为如果 \(\frac{p_i}{t_i}\) 相同,这些题在顺序中必然是连续的一段,但同时他们也可以随意互相调换。每一种排列方案对 \(c\) 的承受度是不一样的。

然后我的智熄操作就开始了。我就想,啊对对对,然后就额外单独处理每类 \(\frac{p_i}{t_i}\) 相同的题目,因为顺序可以随便调换,所以一个题如果要尽量得分高,就把他丢最前面,否则丢最后面,然后看看有无 paradox 即可。

然后一顿乱调,然后又 wa 了。

然后发现 \(\frac{p_i}{t_i}\) 不同的题目也可以互相影响,实际上现在每一个题目都有一个 \(\min\) 和一个 \(\max\),这取决于他们能被放置的时间段。到这里基本上就无懈可击了。但由于之前的种种遗留,复杂度被莫名其妙堆到了 \(O(n\log^2_2 n)\),理论上是能过的,但是浮点数运算常数巨大,然后就挂了。后面找了很久才发现可以到 \(O(n\log_2 n)\) 。但又有一个很致命的点,就是精度问题。我的精度一直设的是 eps = 1e-7 ,但其实这只是满足了答案要求的精度,在运算过程中一些地方理论上需要 eps = 1e-14 的精度(就看最小能到多少!!),然而虽然实际上我开 eps = 1e-12 也能过,但这个精度问题实在是把我搞傻了。绷不住了。

最后反正就是过了。虽然这个题看起来很蠢,但要考虑的细节还是有点多,不过主要是因为我想问题不够全面,总是看到一个问题,就直接改,属于是过拟合了。还是要多想啊。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <ctime>
	using namespace std;
	const int N = 200005;
	const double eps = 1e-12;
	const double INF = 1e9;
struct Dt {
	double p, t, tl, tr, w;
}s[N];
bool cmp(Dt x, Dt y) {
	return x.w > y.w;
}
bool cmp1(Dt x, Dt y) {
	return x.p < y.p;
}
	int n = 0, cnt = 0;
	double T = 0;
	bool vis[N];
bool check(double c) {
	int u = 0;
	double Mx = -INF;
	for (int i = 1; i <= n; i++) {
		while (u + 1 < i && abs(s[u + 1].p - s[i].p) > eps) {
			u++;
			Mx = max(Mx, s[u].p * (1 - c * (s[u].tl + s[u].t) / T));
		}
		double w = s[i].p * (1 - c * s[i].tr / T);
		if (abs(Mx - w) > eps && Mx > w)
			return false;
	}
	return true;
}
int main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
		scanf("%lf", &s[i].p);
	for (int i = 1; i <= n; i++) {
		scanf("%lf", &s[i].t);
		T += s[i].t;
		s[i].w = s[i].p / s[i].t;
	}
	sort(s + 1, s + n + 1, cmp);
	int u = 0;
	double T0 = 0;
	for (int i = 1; i <= n; i++)
		vis[i] = false;
	for (int i = 1; i <= n; i++) {
		while (u + 1 < i && abs(s[u + 1].p / s[u + 1].t - s[i].p / s[i].t) > eps) {
			u++;
			T0 += s[u].t;
		}
		if (i == n || abs(s[i].p / s[i].t - s[i + 1].p / s[i + 1].t) > eps) {
			double T1 = T0;
			for (int j = u + 1; j <= i; j++)
				T1 += s[j].t;
			for (int j = u + 1; j <= i; j++)
				s[j].tl = T0, s[j].tr = T1;
		}
	}
	sort(s + 1, s + n + 1, cmp1);
	int cnt = 0;
	double l = 0, r = 1;
	while (l + eps < r) {
		double mid = (l + r) / 2;
		if (check(mid)) l = mid;
		else r = mid;
	}
	printf("%.7f\n", l);
	return 0;
}

标签:Paradox,int,double,eps,Bear,Dt,include,Mx,CF639E
From: https://www.cnblogs.com/kirakiraa/p/18083792

相关文章

  • P10238 [yLCPC2024] F. PANDORA PARADOXXX 题解
    分析考虑时光倒流。对于需要合并的两个连通块\(x,y\),其合并之后的最远点对距离一定是合并之前的两组点对中产生的。在合并的时候枚举点对,取距离最大值即可。由于我们是倒着来的,所有连通块的最远点对距离最大值不减,所以能直接在合并之后取最大值。维护连通块用并查集即可。复杂......
  • Basic认证和Bearer Token认证的区别
    前端发送POST请求服务器端数据时,通过使用两种认证方式:【1】Basic用户名密码认证 【2】Bearertoken认证这两种都是在请求头中存放:Authorization 认证信息 来请求服务端,服务端通过校验认证信息的正确性来判断用户的身份是否合法,那这两种有啥区别呢?? Basictoken和Beare......
  • CodeForces 1936D Bitwise Paradox
    洛谷传送门CF传送门和CF1004FSonyaandBitwiseOR很像。考虑一次询问怎么做。考虑分治,每次只计算左端点在\([l,mid]\),右端点在\([mid+1,r]\)的区间的贡献。对于每个\(i\in[l,mid]\),维护最小的\(j\in[mid+1,r]\)使得\([i,j]\)的或\(\gev\),那么\(\m......
  • JWT Bearer Token 验证
      ASP.NETCoreWebAPI之Token验证:https://blog.csdn.net/fengershishe/article/details/131388577设置token有效时间:1.在生成token时用IMemoryCache缓存,以token值为key,value为空,添加相对缓存时间。2.添加TokenExtractorMiddleware,在Program添加启动中间件:app.UseMiddlewa......
  • 在NET8中使用简化的 AddJwtBearer 认证
    开发环境系统版本:win10.NETSDK:NET8开发工具:vscode参考引用:使用dotnetuser-jwts管理开发中的JSONWeb令牌注意:以下示例中的端口、token等需替换成你的环境中的信息创建项目运行以下命令来创建一个空的Web项目,并添加Microsoft.AspNetCore.Authentication.JwtBea......
  • Mother bear [UVA10945]
    蒟蒻的首篇题解——Motherbear题目大意:一只笨熊只可以理解回文的句子,要你判断句子去掉标点符号、空格后是否回文。思路:1、利用getline()读入整行字符串,并且处理成只有小写/大写字母和数字的字符串。(样例处理结果对照详见①~②分割线内)2、读取到一半必定会出现倒着的(针对于......
  • 关于token的生成格式--Bearer头部说明
    1.Bearer头部:好处在于可以让请求方和服务方都快速而准确地识别Token的传递方式,使得身份验证更加规范化和通用化,便于开发和维护。但并没有更安全,且具体使用须前后一致。2.带Bearer头部的生成和解密如下:publicStringcreateTokenByBao(StringuserId){Datedate=newDate......
  • CF 628 C Bear and String Distance
    题面翻译题目描述:Limak是一只小北极熊。他喜欢单词——只由小写字母构成,长度为n的单词。他规定dist(s,s')的值为s与s'在26个字母中的间距。如,dist(c,e)=dist(e,c)=2,dist(a,z)=dist(z,a)=25。而且,当dist两个单词时,其值为dist第一个字母+dist第二个字母+……如,dist(af,db)=dis......
  • [Unity] 基于 ParadoxNotion FlowCanvas 插件实现技能
    游戏中的技能总是有各种各样的逻辑比如持续性范围技能,魔兽争霸的暴雪风链式技能,博德之门的闪电链持续技能,博德之门的昼明术等等,这些技能都有各自特殊的逻辑,如何让这些技能有一个通用的配置方法像是RPGBuilder会有一个技能编辑器,里面提供了尽可能多的选择来配置技能编辑器......
  • Bearpi的环境编译应用
    OpenHarmony编绎工具链解释应用具体可参考:OpenAtomOpenHarmony编译成功的截图......