题目链接

前面部分和lzz的题解是一样的。

首先将输入点(x,y)变为(-y,x)然后,只需找一个向量与(-y,x)的点积最大,即找一个向量在(-y,x)上的投影最长。此时所有的点都是在x轴上方的,容易发现答案一定是在凸包上的,再继续观察,如果有一个点在凸包而不在上凸包上,那么它的右上角及左上角一定有一个点,因此这个点一定不是最优的,所以答案一定在上凸包上,且可以在上凸包上二分。

对于subtask5,使用线段树,每个节点存储这个区间的凸包,合并凸包的话可以将两个凸包上的点归并后线性做凸包。

从subtask5使用线段树维护静态凸包继续讨论线段树的做法,注意到所有操作只有在尾部加点删点,每次操作又要做到log^2n,显然不能每次操作后重构一路上的节点,那如果对于线段树上的节点[l,r]当n(序列长度)=r时就重做这个凸包呢?如果重复1,2操作这样就不行了。因此重点要考虑在什么时候重构一个节点的凸包。重构凸包的复杂度是O(len)的,所以可以当n>=r+len时重构这个凸包,这样下次再需要O(len)次撤回才能影响到这个凸包,因此这样重做凸包的次数是均摊O(1)的。查询时如果一个点的凸包没有做出来就要接着查询它的左右儿子,由于每一层只有最后一个点的凸包还没被做出,靠左的区间顶多再找一层,最右边的区间满了但是凸包没做出来,因此还要一直向右找O(logn)个节点(左边的已经做出来了)直到叶子,因此查询的总复杂度为O(log^2n)。

注意一下凸包上不能有三点共线,不然二分时可能会抛弃最优解。

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
//#define P puts("lala")
#define cp cerr<<"lala"<<endl
#define pl puts("lala")
#define se second
#define fi first
#define ln putchar('\n')
#define mkp make_pair
#define pb push_back
using namespace std;
typedef pair<int,int> pii;
inline void read(int &re)
{
char ch=getchar();int g=1;
while(ch<'0'||ch>'9') {if(ch=='-') g=-1;ch=getchar();}
re=0;
while(ch<='9'&&ch>='0') re=(re<<1)+(re<<3)+ch-48,ch=getchar();
re*=g;
}
typedef long long ll;
inline void read(ll &re)
{
char ch=getchar();ll g=1;
while(ch<'0'||ch>'9') {if(ch=='-') g=-1;ch=getchar();}
re=0;
while(ch<='9'&&ch>='0') re=(re<<1)+(re<<3)+ch-48,ch=getchar();
re*=g;
} const int N=300050;
const int mod=998244353;
struct point
{
int x,y;
point(int x=0,int y=0) : x(x),y(y) { }
};
inline bool operator < (point a,point b) {return a.x<b.x||(a.x==b.x&&a.y<b.y);}
inline bool operator == (point a,point b) {return a.x==b.x&&a.y==b.y;}
point operator + (point a,point b) {return point(a.x+b.x,a.y+b.y);}
point operator - (point a,point b) {return point(a.x-b.x,a.y-b.y);}
inline ll cross(point a,point b) {return (ll)a.x*b.y-(ll)a.y*b.x;}
inline ll dot(point a,point b) {return (ll)a.x*b.x+(ll)a.y*b.y;} int n=0; int tot=0;
vector<point>s[N<<2]; vector<point>c; point p[N],poly[N]; vector<point> merge(vector<point> &a,vector<point> &b)
{
c.clear();
int num=0,i=0,j=0,siza=a.size(),sizb=b.size();
while(i<siza&&j<sizb)
{
if(a[i]<b[j]) p[num++]=a[i],i++;
else p[num++]=b[j],j++;
}
while(i<siza) p[num++]=a[i],i++;
while(j<sizb) p[num++]=b[j],j++; int k=0;
//>= !!! no three dot on a line
for(i=0;i<num;++i)
{
while(k>1&&cross(p[i]-poly[k-2],poly[k-1]-poly[k-2])>=0) k--;
poly[k++]=p[i];
}
int m=k;
for(i=num-2;i>=0;--i)
{
while(k>m&&cross(p[i]-poly[k-2],poly[k-1]-poly[k-2])>=0) k--;
poly[k++]=p[i];
}
for(i=k-1;i>=m;--i) c.pb(poly[i]);
if(m-1>0) c.pb(poly[m-1]);
return c;
} ll query(int wh,point P)
{
int l=0,r=s[wh].size()-1;
if(s[wh].size()==1) return dot(s[wh][0],P);
if(l==r) return max(dot(s[wh][0],P),dot(s[wh][1],P));
while(l<r)
{
int mid=l+r>>1;
if(dot(s[wh][mid],P)<dot(s[wh][mid+1],P)) l=mid+1;
else r=mid;
}
return dot(s[wh][l],P);
} point a[N]; int T,top=0; void build(int o,int l,int r)
{
if(l==r) {s[o].pb(a[l]);return ;}
int mid=l+r>>1;
build(o<<1,l,mid); build(o<<1|1,mid+1,r);
s[o]=merge(s[o<<1],s[o<<1|1]);
} void update(int o,int l,int r,int x,point P)
{
if(l==r) {s[o].clear(); s[o].pb(P); return ;}
int mid=l+r>>1;
if(x<=mid) update(o<<1,l,mid,x,P);
else update(o<<1|1,mid+1,r,x,P); if(top==r&&l!=1)
{
o--;
s[o]=merge(s[o<<1],s[o<<1|1]);
}
} void del(int o,int l,int r,int x)
{
if(l==r) {s[o].clear(); return ;}
int mid=l+r>>1;
if(x<=mid) del(o<<1,l,mid,x);
else del(o<<1|1,mid+1,r,x);
if(top<=r) s[o].clear();
} ll qry(int o,int l,int r,int x,int y,point P)
{
if(x<=l&&r<=y&&s[o].size()) return query(o,P);
int mid=l+r>>1;
ll maxn=-9e18;
if(x<=mid) maxn=qry(o<<1,l,mid,x,y,P);
if(y>mid) maxn=max(maxn,qry(o<<1|1,mid+1,r,x,y,P));
return maxn;
} void wj()
{
#ifndef ONLINE_JUDGE
freopen("congroo.in","r",stdin);
freopen("congroo.out","w",stdout);
#endif
}
int main()
{
wj();int i,j,opt,tp;
a[0]=point(0,0);
read(tp);
while(1)
{
read(T);
if(!T) break;
while((1<<tot)<T) tot++;
tot=1<<tot;
for(i=1;i<=(tot<<1);++i) s[i].clear();
int ans=0; top=0;
for(int cas=1;cas<=T;++cas)
{
read(opt);
if(opt==1)
{
int x,y;read(x);read(y);
top++;
a[top]=point(x,y);
update(1,1,tot,top,a[top]);
}
else if(opt==2)
{
a[top]=point(0,0);
del(1,1,tot,top); top--;
}
else
{
int l,r,x,y;read(l);read(r);read(x);read(y);
ll maxn=qry(1,1,tot,l,r,point(-y,x));
//printf("%lld\n",maxn);
ans^=(int)((maxn%mod+mod)%mod);
}
}
printf("%d\n",ans);
}
return 0;
}

集训队互测2016Unknown(UOJ191)的更多相关文章

  1. 【loj2461】【2018集训队互测Day 1】完美的队列

    #2461. 「2018 集训队互测 Day 1」完美的队列 传送门: https://loj.ac/problem/2461 题解: 直接做可能一次操作加入队列同时会弹出很多数字,无法维护:一个操作 ...

  2. 【2018集训队互测】【XSY3372】取石子

    题目来源:2018集训队互测 Round17 T2 题意: 题解: 显然我是不可能想出来的……但是觉得这题题解太神了就来搬(chao)一下……Orzpyz! 显然不会无解…… 为了方便计算石子个数,在 ...

  3. 洛谷 P4463 - [集训队互测 2012] calc(多项式)

    题面传送门 & 加强版题面传送门 竟然能独立做出 jxd 互测的题(及其加强版),震撼震撼(((故写题解以祭之 首先由于 \(a_1,a_2,\cdots,a_n\) 互不相同,故可以考虑求出 ...

  4. UOJ#191. 【集训队互测2016】Unknown 点分治 分治 整体二分 凸包 计算几何

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ191.html 题目传送门 - UOJ191 题意 自行移步集训队论文2016中罗哲正的论文. 题解 自行 ...

  5. LOJ3069. 「2019 集训队互测 Day 1」整点计数(min_25筛)

    题目链接 https://loj.ac/problem/3069 题解 复数真神奇. 一句话题意:令 \(f(x)\) 表示以原点 \((0, 0)\) 为圆心,半径为 \(x\) 的圆上的整点数量, ...

  6. UOJ#191. 【集训队互测2016】Unknown

    题意:维护一个数列,每个元素是个二维向量,每次可以在后面加一个元素或者删除一个元素.给定P(x,y),询问对于[l,r]区间内的元素$S_i$,$S_i \times P$的最大值是多少. 首先简单地 ...

  7. 【集训队互测2015】Robot

    题目描述 http://uoj.ac/problem/88 题解 维护两颗线段树,维护最大值和最小值,因为每次只有单点查询,所以可以直接在区间插入线段就可以了. 注意卡常,不要写STL,用链表把同类修 ...

  8. EZ 2018 05 06 NOIP2018 慈溪中学集训队互测(五)

    享受爆零的快感 老叶本来是让初三的打的,然后我SB的去凑热闹了 TM的T2写炸了(去你妹的优化),T1连-1的分都忘记判了,T3理所当然的不会 光荣革命啊! T1 思维图论题,CHJ dalao给出了 ...

  9. 【纪中集训2019.3.27】【集训队互测2018】小A的旅行(白)

    题目 描述 ​ \(0-n-1\)的图,满足\(n\)是\(2\)的整数次幂, $ i \to j $ 有 $ A_{i,j} $ 条路径: ​ 一条路径的愉悦值定义为起点和终点编号的\(and\)值 ...

随机推荐

  1. 高考集训讲课(To 高一)

    高考集训讲课(To 高一) 主要是怕下午讲着讲着把自己讲懵了,有一定的迷糊概率 经过机房的讨论,一致认为插头\(DP\)实用性不大,所以这次不讲了,先把重要的讲一讲. 顺便吐槽一下,凭什么另外几个人都 ...

  2. 宜宾市黑烟车电子抓拍系统App

    2020.11 - 2021.06负责手机App开发 项目说明:    主要用于管理人员的移动办公,通过与管理平台共享数据库,实现:人工审核.推送交警.账户管理.信息查询.数据统计.点位电子地图.设备 ...

  3. 【Java面试】什么是IO的多路复用机制?

    "什么是IO的多路复用机制?" 这是一道年薪50W的面试题,很遗憾,99%的人都回答不出来. 大家好,我是Mic,一个工作了14年的Java程序员. 今天,给大家分享一道网络IO的 ...

  4. LuoguP4719 【模板】动态 DP(动态DP,LCT)

    \(n \times m\)的算法谁都会吧,注意到每次修改影响的仅是一部分的信息,因此可思考优化. 将每个节点对应一个矩阵\(\begin{bmatrix} g[v][0] & g[v][0] ...

  5. Canvas 非常重要的三个函数

    beginPath 绘制路径必须添加 beginPath().它标志着一个画笔在画布中哪个地方开始画起.没有它,新起的画笔位置必定与上一次画笔结束的位置相连. // 第一个半圆 ctx.arc(60, ...

  6. CF1450E 资本主义Capitalism(差分约束)

    题面 点此看题 没有永远的朋友,只有永远的利益 在这个黑漆漆的社会上,有 n n n 个布衣百姓,他们在利益驱使下成为金钱的奴隶,看不到属于生活的阳光.在茫茫奔途中,他们相互扶持,结交了有 m m m ...

  7. Git Bash(提交文件到GitHub进行托管)

    ​ Introduction 使用Git Bash命令,可以将一个项目上传到Github官网中,进行托管,避免重要文件被误删 1.Git工具下载 Git for Windows 2.在github中新 ...

  8. http服务(postman调用方法及反参)

    #region 监听url #region 监听url路径请求 static HttpListener httpobj; private void listeningUrl() { //提供一个简单的 ...

  9. 好书推荐之Mysql三剑客 :《高性能Mysql》、《Mysql技术内幕》、《数据库索引设计与优化》

    Mysql三剑客系列书籍: 大佬推荐 首先推荐<高性能 MySQL>,这本书是 MySQL 领域的经典之作,拥有广泛的影响力.不但适合数据库管理员(DBA)阅读,也适合开发人员参考学习.不 ...

  10. C# 中的那些锁,在内核态都是怎么保证同步的?

    一:背景 1. 讲故事 其实这个问题是前段时间有位朋友咨询我的,由于问题说的比较泛,不便作答,但想想梳理一下还是能回答一些的,这篇就来聊一聊下面这几个锁. Interlocked AutoResetE ...