BZOJ2716:[Violet 3]天使玩偶
浅谈离线分治算法:https://www.cnblogs.com/AKMer/p/10415556.html
题目传送门:https://lydsy.com/JudgeOnline/problem.php?id=2716
对于每个询问,分为四部分来做。
1、左下角:用\(x+y+tmp\)来更新答案,\(tmp\)表示在这个询问点的左下角的点中\(-x-y\)的最小值。
2、左上角:用\(x-y+tmp\)来更新答案,\(tmp\)表示在这个询问点的左上角的点中\(-x+y\)的最小值。
3、右上角:用\(-x-y+tmp\)来更新答案,\(tmp\)表示在这个询问点的右上角的点中\(x+y\)的最小值。
4、右下角:用\(-x+y+tmp\)来更新答案,\(tmp\)表示在这个询问点的右下角的点中\(x-y\)的最小值。
然后一开始就把序列排好序,像整体二分一样先统计当前层的信息再分流递归下去。略微卡常。
时间复杂度:\(O((n+m)log^2(n+m))\)
空间复杂度:\(O(n+m)\)
代码如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define low(i) ((i)&(-(i)))
const int maxn=5e5+5;
int ans[maxn];
int n,m,ans_cnt,maxlen;
int read() {
int x=0,f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
return x*f;
}
struct Oper {
int opt,id,x,y,tim;
Oper() {}
Oper(int _opt,int _id,int _x,int _y,int _tim) {
opt=_opt,id=_id,x=_x,y=_y,tim=_tim;
}
}p[maxn<<1],tmp[maxn<<1];
struct tree_array {
int top;
bool bo[1000005];
int stk[1000005],c[1000005];
void change(int pos,int v) {
for(int i=pos;i<=maxlen;i+=low(i)) {
if(!bo[i])bo[i]=1,stk[++top]=i;
c[i]=min(c[i],v);
}
}
void reset() {
while(top)bo[stk[top]]=0,c[stk[top]]=c[0],top--;
}
int query(int pos) {
int res=c[0];
for(int i=pos;i;i-=low(i))
res=min(res,c[i]);
return res;
}
}T[2];
bool cmp(Oper a,Oper b) {
if(a.x==b.x)return a.tim<b.tim;
return a.x<b.x;
}
void solve(int l,int r) {
if(l==r)return;
int mid=(l+r)>>1;
for(int i=l;i<=r;i++)
if(p[i].opt==1&&p[i].tim<=mid) {
T[0].change(p[i].y,-p[i].x-p[i].y);
T[1].change(maxlen-p[i].y+1,-p[i].x+p[i].y);
}
else if(p[i].opt==2&&p[i].tim>mid) {
ans[p[i].id]=min(ans[p[i].id],p[i].x+p[i].y+T[0].query(p[i].y));
ans[p[i].id]=min(ans[p[i].id],p[i].x-p[i].y+T[1].query(maxlen-p[i].y+1));
}
T[0].reset(),T[1].reset();
for(int i=r;i>=l;i--)
if(p[i].opt==1&&p[i].tim<=mid) {
T[0].change(p[i].y,p[i].x-p[i].y);
T[1].change(maxlen-p[i].y+1,p[i].x+p[i].y);
}
else if(p[i].opt==2&&p[i].tim>mid) {
ans[p[i].id]=min(ans[p[i].id],-p[i].x+p[i].y+T[0].query(p[i].y));
ans[p[i].id]=min(ans[p[i].id],-p[i].x-p[i].y+T[1].query(maxlen-p[i].y+1));
}
T[0].reset(),T[1].reset();
int cnt1=l,cnt2=mid+1;
for(int i=l;i<=r;i++)
if(p[i].tim<=mid)tmp[cnt1++]=p[i];
else tmp[cnt2++]=p[i];
for(int i=l;i<=r;i++)
p[i]=tmp[i];
solve(l,mid),solve(mid+1,r);
}
int main() {
n=read(),m=read();
for(int i=1;i<=n;i++) {
int x=read(),y=read();
p[i]=Oper(1,0,x,y,i);
maxlen=max(maxlen,y);
}
for(int i=0;i<2;i++)
memset(T[i].c,127,sizeof(T[i].c));
memset(ans,127,sizeof(ans));
for(int i=1;i<=m;i++) {
int opt=read(),x=read(),y=read(),id=opt==2?++ans_cnt:0;
p[n+i]=Oper(opt,id,x,y,n+i),maxlen=max(maxlen,y);
}
sort(p+1,p+m+n+1,cmp);
solve(1,n+m);
for(int i=1;i<=ans_cnt;i++)
printf("%d\n",ans[i]);
return 0;
}
BZOJ2716:[Violet 3]天使玩偶的更多相关文章
- [BZOJ2716] [Violet 3]天使玩偶(CDQ分治)
[BZOJ2716] [Violet 3]天使玩偶(CDQ分治) 题面 Ayu 在七年前曾经收到过一个天使玩偶,当时她把它当作时间囊埋在了地下.而七年后 的今天,Ayu 却忘了她把天使玩偶埋在了哪里, ...
- bzoj2648SJY摆棋子&&bzoj2716[Violet 3]天使玩偶*
bzoj2648SJY摆棋子 bzoj2716[Violet 3]天使玩偶 题意: 棋盘上有n个棋子,现在有m个操作,一种是加棋子,一种是查询离某个点最近的棋子.n,m≤500000. 题解: 先将已 ...
- 【kd-tree】bzoj2716 [Violet 3]天使玩偶
#include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define ...
- bzoj2716: [Violet 3]天使玩偶
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...
- BZOJ2716 [Violet 3]天使玩偶 【CDQ分治】
题目 输入格式 输出格式 输入样例 //样例太长就不贴了.... 输出样例 //见原题 提示 题解 我们将曼哈顿距离式子中的绝对值去掉,每次只考虑x,y比当前点小的更新答案. 为了使所有点都对答案进行 ...
- BZOJ2716: [Violet 3]天使玩偶(KD-Tree)
Description Input Output Sample Input 100 100 81 23 27 16 52 58 44 24 25 95 34 2 96 25 8 14 97 50 97 ...
- BZOJ2648: SJY摆棋子&&2716: [Violet 3]天使玩偶
BZOJ2648: SJY摆棋子 BZOJ2716: [Violet 3]天使玩偶 BZOJ氪金无极限... 其实这两道是同一题. 附上2648的题面: Description 这天,SJY显得无聊. ...
- BZOJ 2716: [Violet 3]天使玩偶
2716: [Violet 3]天使玩偶 Time Limit: 80 Sec Memory Limit: 128 MBSubmit: 1473 Solved: 621[Submit][Statu ...
- BZOJ 2716: [Violet 3]天使玩偶( CDQ分治 + 树状数组 )
先cdq分治, 然后要处理点对答案的贡献, 可以以询问点为中心分成4个区域, 然后去掉绝对值(4种情况讨论), 用BIT维护就行了. --------------------------------- ...
- bzoj 2648: SJY摆棋子&&2716: [Violet 3]天使玩偶 --kdtree
2648: SJY摆棋子&&2716: [Violet 3]天使玩偶 Time Limit: 20 Sec Memory Limit: 128 MB Description 这天,S ...
随机推荐
- 内核模块编译时怎样绕过insmod时的版本检查
1.Uboot:每个arm芯片或者海斯芯片都有各自的uboot. 2.但他们的内核版本可以是一样的,主要是跟各自内核的进行的编译选项有关, 31的内核版本里加了版本检查选项“Kernel type-& ...
- 20145230《java学习笔记》第十周学习总结
20145230<Java程序设计>第十周学习总结 教材学习内容总结 网络编程 网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据.程序员所作的事情就是把数据发送到指定的位置,或 ...
- 关于Pytorch的二维tensor的gather和scatter_操作用法分析
看得不明不白(我在下一篇中写了如何理解gather的用法) gather是一个比较复杂的操作,对一个2维tensor,输出的每个元素如下: out[i][j] = input[index[i][j]] ...
- html文件转换成pdf和word
1.html文件转成pdf 采用jar包有itext-asian.jar.itextpdf-5.5.5.jar.itext-pdfa-5.5.5.jar.itext-xtra-5.5.5.jar,为了 ...
- 出现GC overhead limit exceeded 的解决方案
当我在使用MyEclispe IDE创建Maven项目的时候出现 "An internal error occurred during: “Build Project”. GC overh ...
- 深入Spring:自定义注解加载和使用
前言 在工作中经常使用Spring的相关框架,免不了去看一下Spring的实现方法,了解一下Spring内部的处理逻辑.特别是开发Web应用时,我们会频繁的定义@Controller,@Service ...
- 【codevs1069】关押罪犯[noip2010](并查集)
题目描述 Description S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极 不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨 ...
- 使用命令【TLCL】
type command 显示命令的类别 which command 显示可执行程序的位置 help - 得到 shell 内建命令的帮助文档 --help - 显示用法信息 man ...
- Mysql 利用小工具源码
#include "StdAfx.h" #include "Sql.h" #include <windows.h> #include <std ...
- 【整理】C#文件操作大全(SamWang)
[整理]C#文件操作大全(SamWang) 文件与文件夹操作主要用到以下几个类: 1.File类: 提供用于创建.复制.删除.移动和打开文件的静态方法,并协助创建 FileStream 对象. msd ...