# 【BZOJ4311】向量

2063人阅读 评论(0)

Description

1.插入一个向量(x,y)
2.删除插入的第i个向量
3.查询当前集合与(x,y)点积的最大值是多少。如果当前是空集输出0
Input

(x,y)；如果t=2，输入id表示删除第id个向量；否则输入(x,y)，查询

Output

Sample Input

5

1 3 3

1 1 4

3 3 3

2 1

3 3 3
Sample Output

18

15
HINT

n<=200000 1<=x,y<=10^6

Source

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define MAXN 200010
#define GET (ch>='0'&&ch<='9')
#define LL long long
#define lchild rt<<1,l,mid
#define rchild rt<<1|1,mid+1,r
#define ln rt<<1
#define rn rt<<1|1
using namespace std;
int n,tp1,tp2,top,tp,newtp;
LL ans[MAXN];
void in(int &x)
{
char ch=getchar();x=0;
while (!GET)    ch=getchar();
while (GET) x=x*10+ch-'0',ch=getchar();
}
struct Query
{
int x,y,l,r;
friend LL operator *(Query a,Query b)   {return (LL)a.x*b.x+(LL)a.y*b.y;}
bool operator <(const Query& a)const    {return x==a.x?y>a.y:x<a.x;}
}q1[MAXN],q2[MAXN],newq[MAXN],sta[MAXN];
struct list
{
Query x;
list *next;
}e[MAXN*10<<1];
struct seg
{
int l,r;
list *prev;
}tree[MAXN<<2];
void build(int rt=1,int l=1,int r=n)
{
tree[rt].l=l;tree[rt].r=r;
if (l==r)   return;
int mid=(l+r)>>1;build(lchild);build(rchild);
}
void insert(int rt,int l,int r,int id)
{
int L=tree[rt].l,R=tree[rt].r,mid=(L+R)>>1;
if (l<=L&&r>=R)
{
e[++top].x=q1[id];e[top].next=tree[rt].prev;tree[rt].prev=&e[top];
return;
}
if (r<=mid) insert(ln,l,r,id);
else    if (l>mid)  insert(rn,l,r,id);
else    insert(ln,l,mid,id),insert(rn,mid+1,r,id);
}
void query(int x)
{
int l=1,r=tp,len,mid1,mid2;
while (l<=r)
{
len=(r-l)/3;mid1=l+len;mid2=r-len;
LL dot1=q2[x]*sta[mid1],dot2=q2[x]*sta[mid2];
if (dot1>dot2)  r=mid2-1,ans[x]=max(ans[x],dot1);
else    l=mid1+1,ans[x]=max(ans[x],dot2);
}
}
void solve(int rt,int l,int r)
{
int mid=(l+r)>>1;
if (l<r)    {solve(ln,l,mid);solve(rn,mid+1,r);}
newtp=0;tp=0;
for (list *i=tree[rt].prev;i;i=i->next) newq[++newtp]=i->x;
if (!newtp) return;sort(newq+1,newq+newtp+1);sta[++tp]=newq[1];
for (int i=2;i<=newtp;i++)
if (newq[i].x!=newq[i-1].x)
{
while (tp>1&&(LL)(sta[tp].y-sta[tp-1].y)*(newq[i].x-sta[tp].x)<=(LL)(newq[i].y-sta[tp].y)*(sta[tp].x-sta[tp-1].x))  tp--;
sta[++tp]=newq[i];
}
for (int i=l;i<=r;i++)
if (q2[i].x)    query(i);
}
int main()
{
in(n);int opt,x,y;build();
for (int i=1;i<=n;i++)
{
in(opt);
if (opt==1) in(x),in(y),q1[++tp1].x=x,q1[tp1].y=y,q1[tp1].l=i,q1[tp1].r=n;
if (opt==2) in(x),q1[x].r=i;
if (opt==3) in(x),in(y),q2[i].x=x,q2[i].y=y;
}
for (int i=1;i<=tp1;i++)    insert(1,q1[i].l,q1[i].r,i);
solve(1,1,n);
for (int i=1;i<=n;i++)
if (q2[i].x)    printf("%lld\n",ans[i]);
}
0
0

* 以上用户言论只代表其个人观点，不代表CSDN网站的观点或立场
个人资料
• 访问：483537次
• 积分：9879
• 等级：
• 排名：第1827名
• 原创：452篇
• 转载：3篇
• 译文：1篇
• 评论：164条
文章分类
异次元の传送门
異次元的傳送門
異次元の傳送門
评论排行
最新评论