point (出处不明)

题目大意:给你n个点,m个操作,每个操作有两个参数k,a把所有满足y>k/(x^a)的点删掉,当然每个点只能被删一次,要求输出每个点时被哪个操作删的,如果最后仍没被删就-1

,保证所有的数都是正数  x,y,k,a都是实数,不超过10^6


这题因为是y>k/(x^a)比较蛋疼,所以把其化成alnx+lny>lnk,然后就可以整体二分了,每次判读左一半的操作能否将每个点删掉,

一个点被删掉,就是存在一个kj,aj使得alnx+lny>lnk,也就是求半平面并,看点是否在其内,但是半平面并不会写,那就求补集的半平面交,在看点是否在其外就OK了


写的比较丑

#include<cmath>
#include<cstdio>
#include<vector>
#include<cassert>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=100011,maxm=100011;
const double inf=1e8;
const double eps=1e-10;
struct Tp{
<span style="white-space:pre">	</span>double x,y; int ans;
<span style="white-space:pre">	</span>void read(){scanf("%lf%lf",&x,&y); x=log2(x); y=log2(y);}
}p[maxn],*wp[maxn];
struct Tq{
<span style="white-space:pre">	</span>double k,a;
<span style="white-space:pre">	</span>void read(){scanf("%lf%lf",&k,&a); k=log2(k);}
}q[maxm];
struct point{
<span style="white-space:pre">	</span>double x,y;
<span style="white-space:pre">	</span>void watch(){printf("(%.5f,%.5f) ",x,y);}
};
point operator +(const point &a,const point &b){return (point){a.x+b.x,a.y+b.y};}
point operator -(const point &a,const point &b){return (point){a.x-b.x,a.y-b.y};}
point operator *(const point &a,const double &k){return (point){a.x*k,a.y*k};}
double operator *(const point &a,const point &b){return a.x*b.y-a.y*b.x;}
struct line{
<span style="white-space:pre">	</span>point p,vec; double k;
<span style="white-space:pre">	</span>void getk(){k=atan2(vec.y,vec.x);}
<span style="white-space:pre">	</span>bool check(const point &x){ // 在上也算 
<span style="white-space:pre">		</span>return (vec*(x-p))>=0;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>bool check_(const point &x){ // 在上不算 
<span style="white-space:pre">		</span>return (vec*(x-p))>0;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>bool operator <(const line &s)const{return k<s.k || k==s.k && vec*(s.p-p)<=0;}
};
point getpoint(const line &a,const line &b){
<span style="white-space:pre">	</span>double k=(b.vec*(a.p-b.p))/(a.vec*b.vec);
<span style="white-space:pre">	</span>return a.p+a.vec*k;
}
inline int sgn(double x){if (x<-eps) return -1; return x>eps;}
bool check(const point &a,const point &b,const point &c,const point &x){
<span style="white-space:pre">	</span>int s=sgn((a-x)*(b-x)); return s==sgn((b-x)*(c-x)) && s==sgn((c-x)*(a-x));
}
int n,m;
void init(){
<span style="white-space:pre">	</span>scanf("%d%d",&n,&m);
<span style="white-space:pre">	</span>for (int i=1;i<=n;++i) p[i].read(),wp[i]=p+i,p[i].ans=-1;
<span style="white-space:pre">	</span>for (int i=1;i<=m;++i) q[i].read();
}
void half_plane_intersection(line seg[],int n,point p[],int &t,int &w){
<span style="white-space:pre">	</span>for (int i=1;i<=n;++i) seg[i].getk(); sort(seg+1,seg+n+1);
<span style="white-space:pre">	</span>t=1,w=0; static line q[maxm];
<span style="white-space:pre">	</span>for (int i=1;i<=n;++i){
<span style="white-space:pre">		</span>while (t<w && !seg[i].check(p[w-1])) --w;
<span style="white-space:pre">		</span>while (t<w && !seg[i].check(p[t])) ++t;
<span style="white-space:pre">		</span>if (w<t || fabs(q[w].k-seg[i].k)>eps){
<span style="white-space:pre">			</span>q[++w]=seg[i]; if (w>t) p[w-1]=getpoint(q[w-1],q[w]);
<span style="white-space:pre">		</span>}
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>while (t<w && !q[t].check(p[w-1])) --w;
<span style="white-space:pre">	</span>if (t+1>=w) return;
<span style="white-space:pre">	</span>p[w]=getpoint(q[t],q[w]);
}
void getok(int lp,int rp,int l,int r,bool ok[]){ // lp,rp是点的区间,l,r是删除区间
<span style="white-space:pre">	</span>// 先用删除区间做半平面交,然后用点去看在不在其中,不在就Ok了 
<span style="white-space:pre">	</span>// y<=k-ax
<span style="white-space:pre">	</span>int n=0,t,w; static line seg[maxm];
<span style="white-space:pre">	</span>for (int i=l;i<=r;++i){
<span style="white-space:pre">		</span>seg[++n].p=(point){0,q[i].k},seg[n].vec=(point){-1,q[i].a};
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>seg[++n].p=(point){inf,inf},seg[n].vec=(point){-1,0};
<span style="white-space:pre">	</span>seg[++n].p=(point){-inf,inf},seg[n].vec=(point){0,-1};
<span style="white-space:pre">	</span>seg[++n].p=(point){-inf,-inf},seg[n].vec=(point){1,0};
<span style="white-space:pre">	</span>seg[++n].p=(point){inf,-inf},seg[n].vec=(point){0,1};
<span style="white-space:pre">	</span>static point p[maxm]; half_plane_intersection(seg,n,p,t,w); // 求出来的是逆时针 
<span style="white-space:pre">	</span>if (t+1>=w){for (int i=lp;i<=rp;++i) ok[i]=1; return;}
<span style="white-space:pre">	</span>for (int i=lp;i<=rp;++i){
<span style="white-space:pre">		</span>int head=t+1,tail=w; point x; x.x=wp[i]->x; x.y=wp[i]->y;
<span style="white-space:pre">		</span>while (head<=tail){
<span style="white-space:pre">			</span>int mid=(head+tail)>>1;
<span style="white-space:pre">			</span>if ((p[mid]-p[t])*(x-p[t])>=0) head=mid+1;
<span style="white-space:pre">			</span>else tail=mid-1;
<span style="white-space:pre">		</span>}
<span style="white-space:pre">		</span>int tmp=head-1;
<span style="white-space:pre">		</span>if (tmp<=t || tmp>=w) ok[i]=1;
<span style="white-space:pre">		</span>else ok[i]=!check(p[t],p[tmp],p[tmp+1],x);
<span style="white-space:pre">	</span>}
}
void solve(int lp,int rp,int l,int r){ // lp,rp是点的区间,l,r是删除区间 
<span style="white-space:pre">	</span>if (lp>rp) return; static bool ok[maxn];
<span style="white-space:pre">	</span>if (l==r){
<span style="white-space:pre">		</span>getok(lp,rp,l,l,ok);
<span style="white-space:pre">		</span>for (int i=lp;i<=rp;++i) if (ok[i]) wp[i]->ans=l; return;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>int mid=(l+r)>>1; getok(lp,rp,l,mid,ok);
<span style="white-space:pre">	</span>static Tp *tmp[maxn]; int cnt=lp-1,res;
<span style="white-space:pre">	</span>for (int i=lp;i<=rp;++i) if (ok[i]) tmp[++cnt]=wp[i]; res=cnt;
<span style="white-space:pre">	</span>for (int i=lp;i<=rp;++i) if (!ok[i]) tmp[++cnt]=wp[i];
<span style="white-space:pre">	</span>for (int i=lp;i<=rp;++i) wp[i]=tmp[i];
<span style="white-space:pre">	</span>solve(lp,res,l,mid); solve(res+1,rp,mid+1,r);
}
void work(){
<span style="white-space:pre">	</span>solve(1,n,1,m); for (int i=1;i<=n;++i) printf("%d\n",p[i].ans);
}
int main(){
<span style="white-space:pre">	</span>init();
<span style="white-space:pre">	</span>work();
<span style="white-space:pre">	</span>return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值