UOJ#191. 【集训队互测2016】Unknown 点分治 分治 整体二分 凸包 计算几何
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ191.html
题目传送门 - UOJ191
题意
自行移步集训队论文2016中罗哲正的论文。
题解
自行移步集训队论文2016中罗哲正的论文。
代码
所以说我就是来存代码的?
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
LL read(){
LL x=0,f=0;
char ch=getchar();
while (!isdigit(ch))
f|=ch=='-',ch=getchar();
while (isdigit(ch))
x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return f?-x:x;
}
const int N=300015,mod=998244353;
int Type,n,m,Q;
vector <int> e[N];
struct Gragh{
static const int M=N;
int cnt,y[M],nxt[M],fst[N];
void clear(){
cnt=1;
memset(fst,0,sizeof fst);
}
void add(int a,int b){
y[++cnt]=b,nxt[cnt]=fst[a],fst[a]=cnt;
}
}qs;
struct Point{
int x,y;
Point(){}
Point(int _x,int _y){
x=_x,y=_y;
}
Point operator - (Point a){
return Point(x-a.x,y-a.y);
}
};
LL Cross(Point a,Point b){
return (LL)a.x*b.y-(LL)b.x*a.y;
}
struct Query{
Point a;//a for cross
int f,x,tmp;
LL ans;
}q[N];
int depth[N],fa[N];
Point P[N];
int new_node(int f,int d){
n++;
e[n].clear(),fa[n]=f,depth[n]=d;
e[f].push_back(n);
e[n].push_back(f);
return n;
}
void build_tree(){
static int st[N],d;
st[d=Q=0]=n=1;
e[n].clear(),fa[n]=0,depth[n]=d;
while (m--){
int opt=read(),L,R,x,y;
if (opt==1){
x=read(),y=read();
d++;
st[d]=new_node(st[d-1],d);
P[n]=Point(x,y);
}
else if (opt==2)
d--;
else if (opt==3){
L=read(),R=read(),x=read(),y=read();
Q++;
q[Q].a=Point(x,y);
q[Q].f=st[L],q[Q].x=st[R];
q[Q].ans=-5e18;
}
}
qs.clear();
for (int i=1;i<=Q;i++)
qs.add(q[i].x,i);
}
int Size,RT;
int size[N],Max[N],vis[N];
void get_root(int x,int pre){
size[x]=1,Max[x]=0;
for (auto y : e[x])
if (y!=pre&&!vis[y]){
get_root(y,x);
size[x]+=size[y];
Max[x]=max(Max[x],size[y]);
}
Max[x]=max(Max[x],Size-size[x]);
if (Max[x]<Max[RT])
RT=x;
}
void get_size(int x,int pre){
size[x]=1;
for (auto y : e[x])
if (y!=pre&&!vis[y])
get_root(y,x),size[x]+=size[y];
}
Point A[N];
int qid[N],qtot;
void get_query(int x){
for (int id=qs.fst[x];id;id=qs.nxt[id])
if (depth[q[qs.y[id]].f]<=depth[RT])
qid[++qtot]=qs.y[id];
for (auto y : e[x])
if (y!=fa[x]&&!vis[y])
get_query(y);
}
bool cmp(int a,int b){
return q[a].tmp<q[b].tmp;
}
bool cmp2(int a,int b){
return Cross(q[a].a,q[b].a)<0;
}
Point tmp[N];
int Tmp[N];
void Unknown(int *qid,int qt,Point *P,int &pt){
if (pt<=1)
return (void)sort(qid+1,qid+qt+1,cmp2);
int mid=pt>>1,ls=mid,rs=pt-mid,kk=0;
while (kk<qt&&q[qid[kk+1]].tmp<mid)
kk++;
for (int i=kk+1;i<=qt;i++)
q[qid[i]].tmp-=mid;
Unknown(qid,kk,P,ls);
Unknown(qid+kk,qt-kk,P+mid,rs);
for (int i=kk+1,j=1;i<=qt;i++){
while (j<ls&&Cross(P[j+1]-P[j],q[qid[i]].a)<0)
j++;
q[qid[i]].ans=max(q[qid[i]].ans,Cross(q[qid[i]].a,P[j]));
}
int tot=0,j=1;
for (int i=1;i<=ls;){
Point now=j<=rs&&P[j+mid].x<=P[i].x?P[mid+(j++)]:P[i++];
while (tot>1&&Cross(tmp[tot]-tmp[tot-1],now-tmp[tot-1])>=0)
tot--;
tmp[++tot]=now;
}
for (;j<=rs;j++){
Point now=P[j+mid];
while (tot>1&&Cross(tmp[tot]-tmp[tot-1],now-tmp[tot-1])>=0)
tot--;
tmp[++tot]=now;
}
while (tot>1&&tmp[tot].x==tmp[tot-1].x&&tmp[tot].y<=tmp[tot-1].y)
tot--;
int h=1;
while (h<tot&&tmp[h].x==tmp[h+1].x&&tmp[h].y<=tmp[h+1].y)
h++;
for (int i=h;i<=tot;i++)
P[i-h+1]=tmp[i];
pt=tot-h+1;
tot=0,j=kk+1;
for (int i=1;i<=kk;)
if (j<=qt&&Cross(q[qid[j]].a,q[qid[i]].a)<0)
Tmp[++tot]=qid[j++];
else
Tmp[++tot]=qid[i++];
for (;j<=qt;j++)
Tmp[++tot]=qid[j];
for (int i=1;i<=qt;i++)
qid[i]=Tmp[i];
}
void solve(int x){
Max[RT=0]=N,get_root(x,0),x=RT,get_size(x,0);
int t=0;
for (int i=x;!vis[i];i=fa[i])
A[++t]=P[i];
vis[x]=1,RT=x,qtot=0,get_query(x);
for (int i=1;i<=qtot;i++)
q[qid[i]].tmp=min(t,depth[x]-depth[q[qid[i]].f]+1);
sort(qid+1,qid+qtot+1,cmp);
int k=1;
while (k<=qtot&&q[qid[k]].tmp<t)
k++;
Unknown(qid,k-1,A,t);
sort(qid+k,qid+qtot+1,cmp2);
for (int i=k,j=1;i<=qtot;i++){
while (j<t&&Cross(A[j+1]-A[j],q[qid[i]].a)<0)
j++;
q[qid[i]].ans=max(q[qid[i]].ans,Cross(q[qid[i]].a,A[j]));
}
for (auto y : e[x])
if (!vis[y])
Size=size[y],solve(y);
}
int main(){
Type=read();
while (m=read()){
build_tree(),Size=n;
memset(vis,0,sizeof vis);
vis[0]=1,solve(1);
int ans=0;
for (int i=1;i<=Q;i++)
ans^=(int)((q[i].ans%mod+mod)%mod);
cout << ans << endl;
}
return 0;
}
UOJ#191. 【集训队互测2016】Unknown 点分治 分治 整体二分 凸包 计算几何的更多相关文章
- UOJ#191. 【集训队互测2016】Unknown
题意:维护一个数列,每个元素是个二维向量,每次可以在后面加一个元素或者删除一个元素.给定P(x,y),询问对于[l,r]区间内的元素$S_i$,$S_i \times P$的最大值是多少. 首先简单地 ...
- uoj #190. 【集训队互测2016】消失的源代码 提交答案题
Test 1: 发现是一个字母表的映射 把 \('a' \to 'z'\) 打进去找出映射就好了QAQ . Test 2: 求助 \(dalao\) 得知的点.. 答案是 : \(2016x^2 + ...
- 【loj2461】【2018集训队互测Day 1】完美的队列
#2461. 「2018 集训队互测 Day 1」完美的队列 传送门: https://loj.ac/problem/2461 题解: 直接做可能一次操作加入队列同时会弹出很多数字,无法维护:一个操作 ...
- 【2018集训队互测】【XSY3372】取石子
题目来源:2018集训队互测 Round17 T2 题意: 题解: 显然我是不可能想出来的……但是觉得这题题解太神了就来搬(chao)一下……Orzpyz! 显然不会无解…… 为了方便计算石子个数,在 ...
- 洛谷 P4463 - [集训队互测 2012] calc(多项式)
题面传送门 & 加强版题面传送门 竟然能独立做出 jxd 互测的题(及其加强版),震撼震撼(((故写题解以祭之 首先由于 \(a_1,a_2,\cdots,a_n\) 互不相同,故可以考虑求出 ...
- 【uoj#94】【集训队互测2015】胡策的统计(集合幂级数)
题目传送门:http://uoj.ac/problem/94 这是一道集合幂级数的入门题目.我们先考虑求出每个点集的连通生成子图个数,记为$g_S$,再记$h_S$为点集$S$的生成子图个数,容易发现 ...
- 【集训队互测2015】Robot
题目描述 http://uoj.ac/problem/88 题解 维护两颗线段树,维护最大值和最小值,因为每次只有单点查询,所以可以直接在区间插入线段就可以了. 注意卡常,不要写STL,用链表把同类修 ...
- LOJ3069. 「2019 集训队互测 Day 1」整点计数(min_25筛)
题目链接 https://loj.ac/problem/3069 题解 复数真神奇. 一句话题意:令 \(f(x)\) 表示以原点 \((0, 0)\) 为圆心,半径为 \(x\) 的圆上的整点数量, ...
- BZOJ3938 & UOJ88:[集训队互测2015]Robot——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=3938 http://uoj.ac/problem/88 小q有n只机器人,一开始他把机器人放在了一 ...
随机推荐
- Linux下怎样搜索文件
使用linux系统难免会忘记文件所在的位置,可以使用以下命令对系统中的文件进行搜索.搜索文件的命令为”find“:”locate“:”whereis“:”which“:”type“ 方法/步骤 ...
- Ex3_7无向图二部图_十一次作业
(a) 从图中的某个顶点做深度优先遍历,并将不同层的顶点标记为红黑两种颜色,使得每条树边的两个顶点的颜色都不相同,如果遇到一条回边并且两个顶点的颜色都相同则说明图不是二部图. (b)如果存在一个长度为 ...
- Java链表讲解
主要讲述几点: 一.链表的简介 二.链表实现原理和必要性 三.单链表示例 四.双链表示例 一.链表的简介 链表是一种比较常用的数据结构,链表虽然保存比较复杂,但是在查询时候比较便捷,在多种计算机语言都 ...
- Oracle 口令文件:即 oracle密码文件
一:文件路径位置 [oracle@localhost db_1]$ cd $ORACLE_HOME/dbs [oracle@localhost dbs]$ ls dbsorapwPROD1 hc_or ...
- ionic3 点击input 弹出白色遮罩 遮挡上部内容
在Manifest中的activity里设置android:windowSoftInputMode为adjustPan,默认为adjustResize,当前窗口的内容将自动移动以便当前焦点从不被键盘覆 ...
- 第九单元 利用vi编辑器创建和编辑正文文件
vi编辑器简介 什么是vi vi编辑器的操作模式 vi编辑器的3种基本模式 在vi编辑器中光标的移动 移动光标位置的键与光标移动间的关系 进入插入模式 从命令行模式进入插入模式的命令 在命令行模式下 ...
- 基于Form组件实现的增删改和基于ModelForm实现的增删改
一.ModelForm的介绍 ModelForm a. class Meta: model, # 对应Model的 fields=None, # 字段 exclude=None, # 排除字段 lab ...
- LeetCode(90):子集 II
Medium! 题目描述: 给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 说明:解集不能包含重复的子集. 示例: 输入: [1,2,2] 输出: [ [2], [1 ...
- LeetCode(67):二进制求和
Easy! 题目描述: 给定两个二进制字符串,返回它们的和(用二进制表示). 输入为非空字符串且只包含数字 1 和 0. 示例 1: 输入: a = "11", b = " ...
- Allegro PCB Design GXL (legacy) 刷新PCB封装(Package)中的焊盘(Padstack)
Allegro PCB Design GXL (legacy) version 16.6-2015 “人有失足,马有失蹄”. 像这个电位器的封装的Pin 6,在制作Padstack时,因没有添加SOL ...