codeforces 678F
来源:互联网 发布:mac复制文字 编辑:程序博客网 时间:2024/05/07 13:20
codeforces 678F
有三种操作
1.将点(x,y)加入集合
2.删掉第i次操作加入的点
3.给一个数q,求x*q+y的最大值,如果当前集合为空输出”EMPTY SET”
并不会动态维护凸包,据说是用平衡树啥的。。。
换个角度想,对于每一个点都有一个存在区间[l,r],所以我们可以搞一个线段树出来,将每个点标记到线段中,然后对于每一个线段都维护一个上凸壳,然后三分求答案。
因为对于每一个点,如果将所有的标记都打上肯定是不行的,这样的话就是O(n^2),所以类似于lazy标记的样子,每个点只插入到logn个线段内,而且每个线段上的凸壳点数会少一些,均摊下来大概是O(n(logn)^2)
注意的几个点就是求上凸壳的做法,以及ans的最小值,开到-1e19大概就够了
附上代码
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<vector>using namespace std;#define MAXN 300000#define INF (long long)99999999999999999999struct point{ long long x,y; point(){} point(long long _x,long long _y) { x=_x;y=_y; } friend point operator +(point a,point b) { return point(a.x+b.x,a.y+b.y); } friend point operator -(point a,point b) { return point(a.x-b.x,a.y-b.y); } friend long long operator ^(point a,point b) { return a.x*b.y-a.y*b.x; } friend long long operator *(point a,point b) { return a.x*b.x+a.y*b.y; } friend bool operator <(point a,point b) { return a.x==b.x?a.y<b.y:a.x<b.x; }};struct segment_tree{ int l,r; vector<point> s;};point s[MAXN+50];point stack[MAXN+50];int top;int l[MAXN+50],r[MAXN+50];int op[MAXN+50];segment_tree t[5*MAXN+50];long long ans[MAXN+50];int flag_empty[MAXN+50];int n;void build(int p,int l,int r){ t[p].l=l; t[p].r=r; t[p].s.clear(); if (l==r) { return; } int mid=(l+r)>>1; build(p<<1,l,mid); build(p<<1|1,mid+1,r);}void add(int p,int l,int r,int x){ if (t[p].l==l && t[p].r==r) { t[p].s.push_back(s[x]); return; } int mid=(t[p].l+t[p].r)>>1; if (r<=mid) { add(p<<1,l,r,x); return; } if (l>mid) { add(p<<1|1,l,r,x); return; } add(p<<1,l,mid,x); add(p<<1|1,mid+1,r,x);}void ask(int x){ int L=1,R=top; int mid1,mid2; while (L+3<=R) { mid1=(L*2+R)/3; mid2=(L+R*2)/3; if ((s[x]*stack[mid1])<(s[x]*stack[mid2])) { L=mid1; } else { R=mid2; } } for (int i=L;i<=R;i++) { ans[x]=max(ans[x],stack[i]*s[x]); }}void get(int p){ if (t[p].l!=t[p].r) { get(p<<1); get(p<<1|1); } sort(t[p].s.begin(),t[p].s.end()); top=0; int nown=t[p].s.size(); for (int i=0;i<nown;i++) { while (top>1 && ((stack[top]-stack[top-1])^(t[p].s[i]-stack[top]))>=0) top--; top++; stack[top]=t[p].s[i]; } for (int i=t[p].l;i<=t[p].r;i++) { if (op[i]==3 && flag_empty[i]) ask(i); }}int main(){ scanf("%d",&n); memset(l,0,sizeof(l)); memset(r,0,sizeof(r)); int now=0; for (int i=1;i<=n;i++) { scanf("%d",&op[i]); if (op[i]==1) { scanf("%I64d%I64d",&s[i].x,&s[i].y); l[i]=i; r[i]=n; now++; } else { scanf("%I64d",&s[i].x); s[i].y=1; } if (op[i]==2) { r[s[i].x]=i; now--; } flag_empty[i]=now; ans[i]=-INF; } build(1,1,n); for (int i=1;i<=n;i++) { if (op[i]==1) { add(1,l[i],r[i],i); } } get(1); for (int i=1;i<=n;i++) { if (op[i]!=3) continue; if (flag_empty[i]) { printf("%I64d\n",ans[i]); } else { printf("EMPTY SET\n"); } } return 0;}
1 0
- codeforces 678F
- Codeforces 659F F
- Codeforces 234 F. Fence
- 【Codeforces 500F】Dp
- codeforces 234F - Fence
- F-Logo Turtle codeforces
- 【CODEFORCES】 F. Ant colony
- Codeforces 567F
- CodeForces 241F Race
- Codeforces 611F 思维
- Codeforces 542F 构造
- codeforces 626f
- codeforces 622f
- codeforces 628F
- codeforces 652F
- codeforces 632F
- codeforces 653F
- codeforces 618F
- 玩转CSDN之自定义博客栏目
- JavaSE面向对象--QuickHit
- SwitchPreference响应点击事件
- swiper中加了autoheight后swiper-wrapper的高度显示不正确的解决方法
- 欢迎使用CSDN-markdown编辑器
- codeforces 678F
- 【nova】【nova-network】nova-network在FlatDHCP模型下给VM分配多网卡
- mvc中signalr实现一对一的聊天
- uCOS-II任务间通信之全局变量 [转载]
- 二叉树题目整理
- Windows 10 下Maven的系统环境变量,
- 模拟实现strcpy函数
- centos 7 安装Google earth
- Intersection of Two Linked Lists