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

2025杭电多校第七场 矩形框选、伤害冷却比 个人题解

伤害冷却比

#数学

题目

image

思路

a=KNa=\frac{K}{N}a=NK,则有f(x)=x(⌊ax⌋+1)f(x)=x\left( \left\lfloor \frac{a}{x} \right\rfloor +1\right)f(x)=x(xa+1)
大致画出图像,可得下图
image

若要求区间[L,R][L,R][L,R]上的最大值,则需要求出f(R)f(R)f(R)与红线蓝线交点值之间的最大值

为了求出交点,联立两个方程:
x+a=x(⌊ax⌋+1)x+a=x⌊ax⌋+xax=⌊ax⌋∃n∈Z,ax=n∴x=an,n=1,2,3,…\begin{align} x+a&=x\left( \left\lfloor \frac{a}{x} \right\rfloor +1 \right)\\ \\ x+a&=x\left\lfloor \frac{a}{x} \right\rfloor +x\\ \\ \frac{a}{x}&=\left\lfloor \frac{a}{x} \right\rfloor \\ \\ \exists \ n\in& Z\ , \frac{a}{x}=n\\ \\ \therefore x=\frac{a}{n}&,n=1,2,3,\dots \end{align} x+ax+axa nx=na=x(xa+1)=xxa+x=xaZ ,xa=n,n=1,2,3,
因此可以找到距离RRR最近的x0=anx_{0}=\frac{a}{n}x0=na,其中n=⌈aR⌉n=\left\lceil \frac{a}{R} \right\rceiln=Ra
再将此x0x_{0}x0带入y=x+ay=x+ay=x+a中,即可得到区间[L,R][L,R][L,R]上交点的最大值啦

随后将RRR带入f(x)f(x)f(x)中,比较二者大小约分输出即可

代码实现

#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<queue>
#include<cmath>
#include<unordered_map>
#include<unordered_set>
#include<string.h>
using namespace std;
using ll = long long;
#define rep(i, a, b) for(ll i = (a); i <= (b); i ++)
#define per(i, a, b) for(ll i = (a); i >= (b); i --)
#define see(stl) for(auto&ele:stl)cout<<ele<<" "; cout<<'\n';
#define mid ((l+r)>>1)
#define double long double
#define int ll
int gcd(int a,int b){if(b==0)return a;return gcd(b,a%b);
}void eachT(){int K,N,A,B,C,D;cin>>K>>N>>A>>B>>C>>D;int n=ceil(1.0*(K*D)/(N*C));double x=1.0*K/(N*n);double ans1=x+(1.0*K/N);double L=1.0*A/B;if(L>x)ans1=-1;double ans2=1.0*C/D*(K*D/(N*C)+1);if(ans1>=ans2){int g=gcd(K*(1+n),N*n);cout<<K*(1+n)/g<<"/"<<N*n/g<<'\n';}else{int g=gcd(C*(K*D/(N*C)+1),D);cout<<C*(K*D/(N*C)+1)/g<<"/"<<D/g<<'\n';}
}signed main(){ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);int t=1;cin>>t;while(t--)eachT();
}

矩形框选

#线段树 #扫描线 #二维数点 #差分 #区间最值

题目

image

思路

先讲一讲二维数点的一个常用技巧:
image

假设红框是当前的矩形,长宽固定;a,b,ca,b,ca,b,c为平面内的三个点,现在考虑能够将三个点都选中的区域在哪

过三个点都向左下作与红框大小一致的矩形,三个矩形的交集(蓝色区域)记为MMM,点m∈Mm\in MmM,则以mmm点为左下角的红框都必定可以框住a,b,ca,b,ca,b,c三个点

因此数点问题转换为了染色问题!

在确定了一个矩形选取的形状之后,可以让每个平面内的点都给其左下角的矩形区域进行+1+1+1操作,最后整个平面内哪个点的值最大,其值就是能够框住的点的数量的最大值

如何快速实现二维染色呢 ?
可以通过差分标记+线段树维护扫描线来实现:

  • 线段树维护扫描线上的区间最大值,同时需要区间修改功能
  • 假设扫描线为平行于yyy轴的直线,从左到右扫描
  • 遇到一个矩形的入边,在扫描线上区间加
  • 遇到一个矩形的出边,在扫描线上区间减
  • 每处理完一个横坐标,就调用sum[root]sum[root]sum[root]获取扫描线的线段树根节点所维护的最大值,更新全局最大值

但刚刚说的全都是建立在矩形形状确定的条件下
因此我们还需要解决矩形形状的问题:

nnn最大为1e51e 51e5,那么可以枚举矩形长xxx,则宽y=⌊kx⌋y=\left\lfloor \frac{k}{x} \right\rfloory=xk,在保证矩形面积尽可能大的同时不遗漏情况
x×x≤kx\times x\leq kx×xk作为循环条件,则x≤kx\leq \sqrt{ k }xkkkknnn为同一量级,所以枚举次数为1e2.5=1e2×10=3e21e 2.5=1e 2\times \sqrt{ 10 }=3e 21e2.5=1e2×10=3e2
对于一个确定的矩形形状,扫描线+线段树的复杂度为nlog⁡n=1e6n\log n=1e 6nlogn=1e6TTT组数为1e21e 21e2,总复杂度为3e103e 103e10,在8s8s8s的限制下可以通过

代码实现

#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<queue>
#include<cmath>
#include<unordered_map>
#include<unordered_set>
#include<string.h>
using namespace std;
using ll = long long;
#define int ll
#define rep(i, a, b) for(int i = (a); i <= (b); i ++)
#define per(i, a, b) for(ll i = (a); i >= (b); i --)
#define see(stl) for(auto&ele:stl)cout<<ele<<" "; cout<<'\n';
#define ls p<<1
#define rs p<<1|1
#define mid ((l+r)>>1)
const int N = 1e4 + 5;
// int a[N][N];struct no {int x, y, w;
};
struct q {int down, up, val;
};
struct L {vector<q>query;
}line[N];int ma[N << 2], tag[N << 2];void pushup(int p) {ma[p] = max(ma[ls], ma[rs]);
}void pushdown(int p) {if (!tag[p]) return;tag[ls] += tag[p]; ma[ls] += tag[p];tag[rs] += tag[p]; ma[rs] += tag[p];tag[p] = 0;
}void modify(int p, int l, int r, int x, int y, int val) {if (x <= l && r <= y) { ma[p] += val; tag[p] += val; return; }pushdown(p);if (x <= mid)modify(ls, l, mid, x, y, val);if (y > mid)modify(rs, mid + 1, r, x, y, val);pushup(p);
}void build(int p, int l, int r) {ma[p] = tag[p] = 0;if (l == r)return;build(ls, l, mid), build(rs, mid + 1, r);
}void init(int X, int Y) {rep(i, 0, X + 1) {line[i].query.clear();}build(1, 1, Y);
}void eachT() {int n, k; cin >> n >> k;vector<no>node(n + 1);int X = 0, Y = 0;rep(i, 1, n) {int x, y, v; cin >> x >> y >> v;node[i] = { x,y,v };X = max(X, x), Y = max(Y, y);}int ans = 0;for (int p = 1; p * p <= k; p++) {int y = k / p, x = p;rep(t, 1, 2) {swap(x, y);init(X, Y);rep(i, 1, n) {int x0 = node[i].x, y0 = node[i].y, w = node[i].w;line[max(x0 - x + 1, 1ll)].query.push_back({ max(y0 - y + 1,1ll),y0,w });line[x0 + 1].query.push_back({ max(y0 - y + 1,1ll),y0,-w });}rep(i, 1, X) {for (auto& ele : line[i].query) {int down = ele.down, up = ele.up, val = ele.val;modify(1, 1, Y, down, up, val);}int cmp = ma[1];ans = max(ans, cmp);}}}cout << ans << '\n';
}
signed main() {ios::sync_with_stdio(0);cin.tie(0), cout.tie(0);int t = 1;cin >> t;while (t--)eachT();
}
http://www.xdnf.cn/news/17570.html

相关文章:

  • Ansible 详细笔记
  • 高性能web服务器Nginx
  • Linux 系统运维、网络、SQL Server常用命令
  • Mac如何安装telnet命令
  • 3D文档控件Aspose.3D实用教程:在 C# 中将 3MF 文件转换为 STL
  • 深度学习与遥感入门(六)|轻量化 MobileNetV2 高光谱分类
  • UNet改进(32):结合CNN局部建模与Transformer全局感知
  • HTTP应用层协议-长连接
  • (25.08)Ubuntu20.04+ROS1复现LIO-SAM
  • 2025年最新原创多目标算法:多目标酶作用优化算法(MOEAO)求解MaF1-MaF15及工程应用---盘式制动器设计,提供完整MATLAB代码
  • 【代码随想录day 18】 力扣 501.二叉搜索树中的众数
  • 力扣热题100------279.完全平方数
  • 吉利汽车7月销量超23.7万辆 同比增长58%
  • 【嵌入式C语言】
  • 【10】微网优联——微网优联 嵌入式技术一面,校招,面试问答记录
  • 数据结构:串、数组与广义表
  • IP分片(IP Fragmentation)
  • 力扣109:有序链表转换二叉搜索树
  • docter的使用、vscode(cursor)和docker的连接,详细分析说明
  • 【3D Gen 入坑(1)】Hunyuan3D-Paint 2.1 安装 `custom_rasterizer` 报错完整排查
  • 面试题-----RabbitMQ
  • MySQL的索引(索引的数据结构-B+树索引):
  • 嵌入式Linnux学习 -- 软件编程2
  • 【已解决】报错:WARNING: pip is configured with locations that require TLS/SSL
  • STM32——system文件夹
  • 【ros-humble】4.C++写法巡场海龟(服务通讯)
  • Spring Boot 中 @Transactional 解析
  • [Oracle] UNPIVOT 列转行
  • Linux kernel network stack, some good article
  • Day 37:早停策略和模型权重的保存