P4169 [Violet]天使玩偶/SJY摆棋子

CDQ分治的题目.

我们发现题目要我们求的\(|A_x-B_x|+|A_y-B_y|\)的绝对值号比较恶心.

试想一下怎么去掉

如果所有的点都在我们当前求的点的左下方(就是只考虑在他坐下方的点对他的贡献). 我们怎么求?

那么就要我们求\(min{A_x-B_x+A_y-B_y}\)(假设\(A\)为询问的点)

那么其实就是让我们求\(A_x+A_y-max(B_x+B_y)\)

也因为要满足左下角的限制

其实就是满足

\(B_x<=A_x\)同时满足\(B_y<=A_y\)中最大的\(B_x+B_y\)

这个是可以直接CDQ的

但是我们只考虑了左下方的点对他的贡献,很明显,这是不够的

那么我们就想办法依次将左上,右上,右下全部转化为左下

就是通过同最大值域的加减来改变他们的左边但不改变相对关系

注意常数就好了

另外,这种情况下归并排序的时间复杂度比快排优秀太多了

#include<bits/stdc++.h>
using namespace std;
const int N = 6e5 + 3;
const int M = 1e6 + 3;
const int INF = 2e9;
int n,m;
int max_x,max_y;
int ans[N];
struct Q{
int type;
int id;
int xi;
int yi;
int ans;
}q[N],p[N],h[N];
Q g[N];
struct BIT{
int c[M];
inline void ins(int x,int v){
for(;x <= max_y;x += x & -x) c[x] = max(c[x],v);
}
inline int query(int x){
int res = 0;
for(;x;x -= x & -x) res = max(res,c[x]);
return res;
}
inline void clear(int x){
for(;x <= max_y;x += x & -x) c[x] = 0;
}
}T;
int xx[N],yy[N];
inline bool cmp1(Q x,Q y){
return x.id < y.id;
}
inline bool cmp2(Q x,Q y){
if(x.xi != y.xi)
return x.xi < y.xi;
return x.yi < y.yi;
}
inline int read(){
int x = 0;int flag = 0;
char ch = getchar();
while(!isdigit(ch)){
if(ch == '-') flag = 1;
ch = getchar();
}
while(isdigit(ch)){
x = (x<<1) + (x<<3) + (ch^'0');
ch = getchar();
}
if(flag) x = -x;
return x;
}
inline void solve(int l,int r){
if(l == r) return;
int mid = (l + r) >> 1;
solve(l,mid);solve(mid + 1,r);
//sort(p + l,p + mid + 1,cmp2);
//sort(p + mid + 1,p + r + 1,cmp2);
// nj printf("%d %d\n",l,r);
int now = l;
int ll = l,rr = mid + 1,nn = l - 1; // cout << 1 << endl;
for(int i = mid + 1;i <= r;++i){
while(i <= r && p[i].type != 2) ++i;
if(i > r) break;
for(;now <= mid && p[now].xi <= p[i].xi;++now) if(p[now].type == 1) T.ins(p[now].yi,p[now].xi + p[now].yi);
int t = T.query(p[i].yi);
if(t) ans[p[i].id] = min(ans[p[i].id],p[i].xi + p[i].yi - t);
}
for(int i = l;i < now;++i) if(p[i].type == 1) T.clear(p[i].yi);
while(ll <= mid && rr <= r){
if(p[ll].xi <= p[rr].xi) h[++nn] = p[ll++];
else h[++nn] = p[rr++];
}
while(ll <= mid) h[++nn] = p[ll++];
while(rr <= r) h[++nn] = p[rr++];
for(int i = l;i <= r;++i) p[i] = h[i];
}
inline void del(){
int rx = 0,ry = 0;m = 0;
for(int i = 1;i <= n;++i)
if(p[i].type == 1) rx = max(p[i].xi,rx),ry = max(p[i].yi,ry);
for(int i = 1;i <= n;++i){
if((p[i].xi <= rx && p[i].yi <= ry) || p[i].type == 2) g[++m] = p[i];
}
for(int i = 1;i <= m;++i) p[i] = g[i];
}
int main(){
n = read(),m = read();
for(int i = 1;i <= n;++i){
q[i].xi = read() + 1,q[i].yi = read() + 1;
max_x = max(max_x,q[i].xi),max_y = max(max_y,q[i].yi);
q[i].id = i;
q[i].type = 1;
}
for(int i = 1;i <= m;++i){
q[n + i].type = read();q[n + i].xi = read() + 1;q[n + i].yi = read() + 1;
q[n + i].id = i + n;
max_x = max(max_x,q[n + i].xi),max_y = max(max_y,q[n + i].yi);
}
n += m;
for(int i = 1;i <= n;++i) p[i] = q[i];
for(int i = 1;i <= n;++i) ans[i] = INF;
max_y = max(max_x,max_y) + 1;
solve(1,n);
for(int i = 1;i <= n;++i) p[i] = q[i],p[i].xi = max_y - p[i].xi;
solve(1,n);
for(int i = 1;i <= n;++i) p[i] = q[i],p[i].yi = max_y - p[i].yi;
solve(1,n);
for(int i = 1;i <= n;++i) p[i] = q[i],p[i].xi = max_y - p[i].xi,p[i].yi = max_y - p[i].yi;
solve(1,n);
for(int i = 1;i <= n;++i) if(ans[i] != INF) printf("%d\n",ans[i]);
return 0;
}

天使玩偶/SJY摆棋子的更多相关文章

  1. bzoj2716/2648 / P4169 [Violet]天使玩偶/SJY摆棋子

    P4169 [Violet]天使玩偶/SJY摆棋子 k-d tree 模板 找了好几天才发现输出优化错了....真是zz...... 当子树非常不平衡时,就用替罪羊树的思想,拍扁重建. luogu有个 ...

  2. 【LG4169】[Violet]天使玩偶/SJY摆棋子

    [LG4169][Violet]天使玩偶/SJY摆棋子 题面 洛谷 题解 至于\(cdq\)分治的解法,以前写过 \(kdTree\)的解法好像还\(sb\)一些 就是记一下子树的横.纵坐标最值然后求 ...

  3. 洛谷 P4169 [Violet]天使玩偶/SJY摆棋子 解题报告

    P4169 [Violet]天使玩偶/SJY摆棋子 题目描述 \(Ayu\)在七年前曾经收到过一个天使玩偶,当时她把它当作时间囊埋在了地下.而七年后 的今天,\(Ayu\) 却忘了她把天使玩偶埋在了哪 ...

  4. luoguP4169 [Violet]天使玩偶/SJY摆棋子 K-Dtree

    P4169 [Violet]天使玩偶/SJY摆棋子 链接 luogu 思路 luogu以前用CDQ一直过不去. bzoj还是卡时过去的. 今天终于用k-dtree给过了. 代码 #include &l ...

  5. 洛谷P4169 [Violet]天使玩偶/SJY摆棋子(CDQ分治)

    [Violet]天使玩偶/SJY摆棋子 题目传送门 解题思路 用CDQ分治开了氧气跑过. 将输入给的顺序作为第一维的时间,x为第二维,y为第三维.对于距离一个询问(ax,ay),将询问分为四块,左上, ...

  6. [Violet]天使玩偶/SJY摆棋子 [cdq分治]

    P4169 [Violet]天使玩偶/SJY摆棋子 求离 \((x,y)\) 最近点的距离 距离的定义是 \(|x1-x2|+|y1-y2|\) 直接cdq 4次 考虑左上右上左下右下就可以了-略微卡 ...

  7. P4169 [Violet]天使玩偶/SJY摆棋子

    题目背景 感谢@浮尘ii 提供的一组hack数据 题目描述 Ayu 在七年前曾经收到过一个天使玩偶,当时她把它当作时间囊埋在了地下.而七年后 的今天,Ayu 却忘了她把天使玩偶埋在了哪里,所以她决定仅 ...

  8. LG4169 [Violet]天使玩偶/SJY摆棋子

    题意 Ayu 在七年前曾经收到过一个天使玩偶,当时她把它当作时间囊埋在了地下.而七年后 的今天,Ayu 却忘了她把天使玩偶埋在了哪里,所以她决定仅凭一点模糊的记忆来寻找它. 我们把 Ayu 生活的小镇 ...

  9. 洛谷P4169 [Violet]天使玩偶/SJY摆棋子

    %%%神仙\(SJY\) 题目大意: 一个二维平面,有两种操作: \(1.\)增加一个点\((x,y)\) \(2.\)询问距离\((x,y)\)曼哈顿最近的一个点有多远 \(n,m\le 300 0 ...

随机推荐

  1. MYSQL中LIMIT用法_后台分页

    LIMIT是MySQL内置函数,其作用是用于限制查询结果的条数. 1)其语法格式如下: LIMIT[位置偏移量,]行数 其中,中括号里面的参数是可选参数,位置偏移量是指MySQL查询分析器要从哪一行开 ...

  2. 洛谷 P1027 Car的旅行路线 最短路+Dijkstra算法

    目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例 输出样例 说明 思路 AC代码 总结 题面 题目链接 P1027 Car的旅行路线 题目描述 又到暑假了,住在 ...

  3. Excel中IP地址排序

    思路 将IP地址按"."分隔,提取"."之间的每个数,然后根据提取出的列从左至右进行主要字段及次要字段排序 公式说明 返回一个字符串在另一个字符串中出现的起始位 ...

  4. 《DL/T 1476-2015 电力安全工器具预防性试验规程》中的样品名称及试验项目

  5. vue插件大全

    一.UI组件及框架 element - 饿了么出品的Vue2的web UI工具套件 mint-ui - Vue 2的移动UI元素 iview - 基于 Vuejs 的开源 UI 组件库 Keen-UI ...

  6. Myeclipse 方法中文注释看不到

    参考以下几种解决方式: 1 改变整个文件类型的编码格式 1) eclipse->window->preferences->General->Content Types 2) 找 ...

  7. python代码实现树莓派3b+驱动步进电机

    python代码实现树莓派3b+驱动步进电机 之前买了个树莓派,刚买回来那会儿热情高涨,折腾了一段时间,然后就放那吃灰了.前几天忽然想起来这个东西了,决定再玩玩儿,于是就从某宝上购买了一套步进电机.驱 ...

  8. A - Archery Tournament 动态开点+vecotor 神仙题

    存图还是像矩形一样的存,每个节点存所在区级内部的圆的编号,然后暴力判断,开始我也有这个想法,但是...这TM也能过...仔细想想,貌似好像是可以过,时间复杂度玄学无法证明.... #include&l ...

  9. centos安装hdp

    1. 准备6和7的 YUM源包 1.1 centos 下载后解压到同一个目录 http://mirrors.163.com/centos/6/isos/x86_64/CentOS-6.9-x86_64 ...

  10. codeforces1253F(图转换为树减少复杂度)

    题意: 给定一个无向图,其中1-k为充电桩,然后给定q个询问\(u_i, v_i\)(都是充电桩),然后问从其中一个充电桩到达另外一个充电桩需要最小的电池的容量. 每经过一条边都需要消耗一定的能量,到 ...