BZOJ4311:向量——题解

本文介绍了一种解决向量集合中点积最大值查询问题的高效算法。通过构建线段树和凸包来实现对动态变化的向量集合进行快速查询,并详细展示了算法的具体实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

https://www.lydsy.com/JudgeOnline/problem.php?id=4311

你要维护一个向量集合,支持以下操作:
1.插入一个向量(x,y)
2.删除插入的第i个向量
3.查询当前集合与(x,y)点积的最大值是多少。如果当前是空集输出0

半个论文题吧……另外当空集的时候没有及时跳出结果WA了debug很难受。

参考:https://blog.youkuaiyun.com/outer_form/article/details/52277030

首先,每个向量都在第一象限,然后根据点积的基本定义,实际上就是给定向量与其他向量投影到给定向量的长度的乘积。

故在向量的无穷远处取一点,过这个点做垂线,然后将垂线往原点移,最先扫到的向量就是答案。

于是我们可以发现答案一定在点集的凸包上。

然而对于每个向量生效时间段不一样,所以我们把点排序后(这样建凸包的时候就不用再排序了)按时间建立线段树完后把点扔上去,然后对于每个区间的点集建立凸包跑一遍。

另外我们还可以发现把询问向量极角排序之后决策点单调(显然决策点是从凸包靠下的点慢慢变成靠上的点),于是跑一遍就可以了。

对于向量的极角排序正好用归并排序连同爬线段树一起做了,所以复杂度为O(nlogn)。

#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=2e5+5;
inline int read(){
    int X=0,w=0;char ch=0;
    while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
    while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    return w?-X:X;
}
struct point{
    ll x,y;
    point(){}
    point(ll a,ll b){x=a,y=b;}
    point operator-(const point &b)const{
        return point(x-b.x,y-b.y);
    }
}q[N],s[N];
struct data{
    point a;
    int l,r;
}p[N];
int n,pcnt,qcnt,tmp[N],t[N];
vector<point>tr[N*4];
ll ans[N];
inline ll multiX(point a,point b){
    return a.x*b.y-b.x*a.y;
}
inline ll multiP(point a,point b){
    return a.x*b.x+a.y*b.y;
}
inline bool cmp(data a,data b){
    point u=a.a,v=b.a;
    return u.x>v.x||(u.x==v.x&&u.y>v.y);
}
void insert(int a,int l,int r,int l1,int r1,point x){
    if(r<l1||r1<l)return;
    if(l1<=l&&r<=r1){
    tr[a].push_back(x);return;
    }
    int mid=(l+r)>>1;
    insert(a<<1,l,mid,l1,r1,x);insert(a<<1|1,mid+1,r,l1,r1,x);
}
void divide(int a,int l,int r){
    if(l==r){
    tmp[l]=l;
    for(int i=0;i<tr[a].size();i++)
        ans[l]=max(ans[l],multiP(q[l],tr[a][i]));
    return;
    }
    int mid=(l+r)>>1;
    divide(a<<1,l,mid);divide(a<<1|1,mid+1,r);
    for(int i=l,j=l,k=mid+1;i<=r;i++){
    if(j<=mid&&(k>r||multiX(q[tmp[j]],q[tmp[k]])>=0))t[i]=tmp[j++];
    else t[i]=tmp[k++];
    }
    for(int i=l;i<=r;i++)tmp[i]=t[i];
    int rr=0;
    for(int i=0;i<tr[a].size();i++){
    while(rr>1&&multiX(tr[a][i]-s[rr-1],s[rr]-s[rr-1])>=0)rr--;
    s[++rr]=tr[a][i];
    }
    if(rr){
    for(int i=l,j=1;i<=r;i++){
        while(j<rr&&multiP(q[tmp[i]],s[j+1])>multiP(q[tmp[i]],s[j]))j++;
        ans[tmp[i]]=max(ans[tmp[i]],multiP(q[tmp[i]],s[j]));
    }
    }
}
int main(){
    n=read();
    for(int i=1;i<=n;i++){
    int op=read();
    if(op==1){
        int x=read(),y=read();
        p[++pcnt].a=point(x,y);
        p[pcnt].l=qcnt+1;
        p[pcnt].r=-1;
    }
    if(op==2){
        int id=read();
        p[id].r=qcnt;
    }
    if(op==3){
        int x=read(),y=read();
        q[++qcnt]=point(x,y);
    }
    }
    sort(p+1,p+pcnt+1,cmp);
    for(int i=1;i<=pcnt;i++){
    if(p[i].r==-1)p[i].r=qcnt;
    if(p[i].l>p[i].r)continue;
    insert(1,1,qcnt,p[i].l,p[i].r,p[i].a);
    }
    divide(1,1,qcnt);
    for(int i=1;i<=qcnt;i++)printf("%lld\n",ans[i]);
    return 0;
}

 

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

转载于:https://www.cnblogs.com/luyouqi233/p/9086969.html

【基于QT的调色板】是一个使用Qt框架开发的色彩选择工具,类似于Windows操作系统中常见的颜色选取器。Qt是一个跨平台的应用程序开发框架,广泛应用于桌面、移动和嵌入式设备,支持C++和QML语言。这个调色板功能提供了横竖两种渐变模式,用户可以方便地选取所需的颜色值。 在Qt中,调色板(QPalette)是一个关键的类,用于管理应用程序的视觉样式。QPalette包含了一系列的颜色角色,如背景色、前景色、文本色、高亮色等,这些颜色可以根据用户的系统设置或应用程序的需求进行定制。通过自定义QPalette,开发者可以创建具有独特视觉风格的应用程序。 该调色板功能可能使用了QColorDialog,这是一个标准的Qt对话框,允许用户选择颜色。QColorDialog提供了一种简单的方式来获取用户的颜色选择,通常包括一个调色板界面,用户可以通过滑动或点击来选择RGB、HSV或其他色彩模型中的颜色。 横渐变取色可能通过QGradient实现,QGradient允许开发者创建线性或径向的色彩渐变。线性渐变(QLinearGradient)沿直线从一个点到另一个点过渡颜色,而径向渐变(QRadialGradient)则以圆心为中心向外扩散颜色。在调色板中,用户可能可以通过滑动条或鼠标拖动来改变渐变的位置,从而选取不同位置的颜色。 竖渐变取色则可能是通过调整QGradient的方向来实现的,将原本水平的渐变方向改为垂直。这种设计可以提供另一种方式来探索颜色空间,使得选取颜色更为直观和便捷。 在【colorpanelhsb】这个文件名中,我们可以推测这是与HSB(色相、饱和度、亮度)色彩模型相关的代码或资源。HSB模型是另一种常见且直观的颜色表示方式,与RGB或CMYK模型不同,它以人的感知为基础,更容易理解。在这个调色板中,用户可能可以通过调整H、S、B三个参数来选取所需的颜色。 基于QT的调色板是一个利用Qt框架和其提供的色彩管理工具,如QPalette、QColorDialog、QGradient等,构建的交互式颜色选择组件。它不仅提供了横竖渐变的色彩选取方式,还可能支持HSB色彩模型,使得用户在开发图形用户界面时能更加灵活和精准地控制色彩。
标题基于Spring Boot的二手物品交易网站系统研究AI更换标题第1章引言阐述基于Spring Boot开发二手物品交易网站的研究背景、意义、现状及本文方法与创新点。1.1研究背景与意义介绍二手物品交易的市场需求和Spring Boot技术的适用性。1.2国内外研究现状概述当前二手物品交易网站的发展现状和趋势。1.3论文方法与创新点说明本文采用的研究方法和在系统设计中的创新之处。第2章相关理论与技术介绍开发二手物品交易网站所涉及的相关理论和关键技术。2.1Spring Boot框架解释Spring Boot的核心概念和主要特性。2.2数据库技术讨论适用的数据库技术及其在系统中的角色。2.3前端技术阐述与后端配合的前端技术及其在系统中的应用。第3章系统需求分析详细分析二手物品交易网站系统的功能需求和性能需求。3.1功能需求列举系统应实现的主要功能模块。3.2性能需求明确系统应满足的性能指标和安全性要求。第4章系统设计与实现具体描述基于Spring Boot的二手物品交易网站系统的设计和实现过程。4.1系统架构设计给出系统的整体架构设计和各模块间的交互方式。4.2数据库设计详细阐述数据库的结构设计和数据操作流程。4.3界面设计与实现介绍系统的界面设计和用户交互的实现细节。第5章系统测试与优化说明对系统进行测试的方法和性能优化的措施。5.1测试方法与步骤测试环境的搭建、测试数据的准备及测试流程。5.2测试结果分析对测试结果进行详细分析,验证系统是否满足需求。5.3性能优化措施提出针对系统性能瓶颈的优化建议和实施方案。第6章结论与展望总结研究成果,并展望未来可能的研究方向和改进空间。6.1研究结论概括本文基于Spring Boot开发二手物品交易网站的主要发现和成果。6.2展望与改进讨论未来可能的系统改进方向和新的功能拓展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值