BZOJ 2716 [Violet 3]天使玩偶 (CDQ分治、树状数组)
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2716
怎么KD树跑得都那么快啊。。我写的CDQ分治被暴虐
做四遍CDQ分治,每次求一个左下角\(x_i+y_i\)的最大值
第一种写法是一开始按时间排序,然后CDQ分治的时候改成按\(x\)坐标排序,同时用树状数组统计每个\(y\)坐标的最大值
第二种写法是一开始按\(x\)坐标排序,然后CDQ分支的时候改成按时间排序
CDQ分治好神奇(琦)。。。
一定要注意树状数组如果没有元素不能返回0! 我这么写然后test1 WA on line 40W+...
代码
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cassert>
#include<algorithm>
using namespace std;
const int N = 1e6;
const int C = 1e6+2;
struct Query
{
int opt,x,y,id,ans;
bool operator <(const Query &arg) const {return id<arg.id;}
} qr[N+3],qr2[N+3];
int tr[C+3];
int n,q,mx;
void modify(int lrb,int val)
{
while(lrb<=mx)
{
tr[lrb] = max(tr[lrb],val);
lrb += (lrb&(-lrb));
}
}
int querymax(int rb)
{
int ret = -C*2;
while(rb>0)
{
ret = max(ret,tr[rb]);
rb -= (rb&(-rb));
}
return ret;
}
void clear(int lrb)
{
while(lrb<=mx && tr[lrb]!=-C*2)
{
tr[lrb] = -C*2;
lrb += (lrb&(-lrb));
}
}
void cdqdc(int lb,int rb)
{
if(lb==rb) return;
int mid = (lb+rb)>>1;
int j = lb,k = mid+1;
for(int i=lb; i<=rb; i++)
{
if(qr[i].id<=mid) {qr2[j] = qr[i]; j++;}
else {qr2[k] = qr[i]; k++;}
}
for(int i=lb; i<=rb; i++) qr[i] = qr2[i];
cdqdc(lb,mid);
cdqdc(mid+1,rb);
j = lb; k = mid+1;
while(k<=rb)
{
while(j<=mid && qr[j].opt==2) j++;
while(k<=rb && qr[k].opt==1) k++;
if(k>rb) break;
while(j<=mid && qr[j].x<=qr[k].x)
{
if(qr[j].opt==1) {modify(qr[j].y,qr[j].x+qr[j].y);}
j++;
}
int tmp = querymax(qr[k].y);
qr[k].ans = min(qr[k].ans,qr[k].x+qr[k].y-tmp);
k++;
}
for(int i=lb; i<=mid; i++) {if(qr[i].opt==1) clear(qr[i].y);}
j = lb; k = mid+1;
for(int i=lb; i<=rb; i++)
{
if(j>mid || (k<=rb && qr[k].x<qr[j].x)) {qr2[i] = qr[k]; k++;}
else {qr2[i] = qr[j]; j++;}
}
for(int i=lb; i<=rb; i++) qr[i] = qr2[i];
}
int main()
{
scanf("%d%d",&n,&q);
for(int i=1; i<=n; i++)
{
scanf("%d%d",&qr[i].x,&qr[i].y); qr[i].opt = 1; qr[i].id = i; qr[i].x++; qr[i].y++; qr[i].ans = C*7;
mx = max(mx,max(qr[i].x,qr[i].y));
}
for(int i=n+1; i<=n+q; i++)
{
scanf("%d%d%d",&qr[i].opt,&qr[i].x,&qr[i].y,&qr[i].opt); qr[i].id = i; qr[i].x++; qr[i].y++; qr[i].ans = C*7;
mx = max(mx,max(qr[i].x,qr[i].y));
}
q+=n;
for(int i=0; i<=mx; i++) tr[i] = -C*2;
cdqdc(1,q);
sort(qr+1,qr+q+1);
for(int i=1; i<=q; i++) {qr[i].x = mx+1-qr[i].x;}
cdqdc(1,q);
sort(qr+1,qr+q+1);
for(int i=1; i<=q; i++) {qr[i].y = mx+1-qr[i].y;}
cdqdc(1,q);
sort(qr+1,qr+q+1);
for(int i=1; i<=q; i++) {qr[i].x = mx+1-qr[i].x;}
cdqdc(1,q);
sort(qr+1,qr+q+1);
for(int i=1; i<=q; i++)
{
if(qr[i].opt==2) printf("%d\n",qr[i].ans);
}
return 0;
}
BZOJ 2716 [Violet 3]天使玩偶 (CDQ分治、树状数组)的更多相关文章
- BZOJ 2716: [Violet 3]天使玩偶( CDQ分治 + 树状数组 )
先cdq分治, 然后要处理点对答案的贡献, 可以以询问点为中心分成4个区域, 然后去掉绝对值(4种情况讨论), 用BIT维护就行了. --------------------------------- ...
- BZOJ 2716 Violet 3 天使玩偶 CDQ分治
题目大意:初始给定平面上的一个点集.提供两种操作: 1.将一个点增加点集 2.查询距离一个点最小的曼哈顿距离 K-D树是啥...不会写... 我仅仅会CDQ分治 对于一个询问,查询的点与这个点的位置关 ...
- [BZOJ2716] [Violet 3]天使玩偶(CDQ分治)
[BZOJ2716] [Violet 3]天使玩偶(CDQ分治) 题面 Ayu 在七年前曾经收到过一个天使玩偶,当时她把它当作时间囊埋在了地下.而七年后 的今天,Ayu 却忘了她把天使玩偶埋在了哪里, ...
- BZOJ 1176 Mokia CDQ分治+树状数组
1176: [Balkan2007]Mokia Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 1854 Solved: 821[Submit][St ...
- BZOJ 2683 简单题 cdq分治+树状数组
题意:链接 **方法:**cdq分治+树状数组 解析: 首先对于这道题,看了范围之后.二维的数据结构是显然不能过的.于是我们可能会考虑把一维排序之后还有一位上数据结构什么的,然而cdq分治却可以非常好 ...
- 【BZOJ4553】[Tjoi2016&Heoi2016]序列 cdq分治+树状数组
[BZOJ4553][Tjoi2016&Heoi2016]序列 Description 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他.玩具上有一个数列,数列中某些项的值可能 ...
- 【bzoj3262】陌上花开 CDQ分治+树状数组
题目描述 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当且仅当Sa&g ...
- 【bzoj2225】[Spoj 2371]Another Longest Increasing CDQ分治+树状数组
题目描述 给定N个数对(xi, yi),求最长上升子序列的长度.上升序列定义为{(xi, yi)}满足对i<j有xi<xj且yi<yj. 样例输入 8 1 3 3 2 1 1 4 5 ...
- LOJ3146 APIO2019路灯(cdq分治+树状数组)
每个时刻都形成若干段满足段内任意两点可达.将其视为若干正方形.则查询相当于求历史上某点被正方形包含的时刻数量.并且注意到每个时刻只有O(1)个正方形出现或消失,那么求出每个矩形的出现时间和消失时间,就 ...
随机推荐
- Android 子线程无法刷新UI界面
问题:在Android开发中,子线程无法直接更改UI界面视图的刷新 这个时候 Handler 起到了至关重要的作用. 简单来说 , Handler就是用来传递消息的. Handler可以当成子线程与主 ...
- BZOJ 1257 余数之和 题解
题面 这道题是一道整除分块的模板题: 首先,知道分块的人应该知道,n/i最多有2*sqrt(n)种数,但这和余数有什么关系呢? 注意,只要n/i的值和n/(i+d)的值一样,那么n%i到n%(i+d) ...
- Luogu P3647 [APIO2014]连珠线
题目 换根dp. 显然对于给定的一棵有根树,蓝线都不能拐弯. 设\(f_{u,0}\)表示\(u\)不是蓝线中点时子树内的答案,\(f_{u,1}\)表示\(u\)是蓝线中点时子树内的答案.(以\(1 ...
- 初识JavaScript(二)
初识JavaScript(二) 我从上一篇<初识JavaScript(一)>知道和认识JavaScript的词法结构,也开始慢慢接触到了JavaScript的使用方法,是必须按照JavaS ...
- 自己动手实现一个html2canvas
前言 昨天写了新手引导动画的4种实现方式,里面用到了 html2canvas 于是就顺便了解了一下实现思路. 大概就是 利用 svg 的 foreignObject 标签, 嵌入 dom, 最后再利用 ...
- 由对称性解2-SAT问题
由对称性解2-SAT问题 (by 伍昱,03年IOI国家集训队论文ppt) 2-SAT: 2-SAT就是2判定性问题,是一种特殊的逻辑判定问题. 2-SAT问题有何特殊性?该如何求解? 我们从一道例题 ...
- homebrew学习(四)之取消homebrew自动更新
homebrew自动更新 使用brew install /brew cask install安装软件总是先updating HomeBrew…,速度很慢 取消homebrew自动更新 方法一:使用命令 ...
- uoj #450[集训队作业2018]复读机
传送门 \(d=1\),那么任何时刻都可以\(k\)个复读机的一种,答案为\(k^n\) \(d>1\),可以枚举某个复读机的复读次数(必须是\(d\)的倍数),然后第\(i\)个复读时间为\( ...
- python接口自动化 - Requests-3 高级用法
高级用法 本篇文档涵盖了 Requests 的一些高级特性. 会话对象 会话对象让你能够跨请求保持某些参数.它也会在同一个 Session 实例发出的所有请求之间保持 cookie, 期间使用 url ...
- 第98:svd原理
SVD分解:任何矩阵都可以分解成第一行的形式,3个相乘.UV都是正交矩阵,中间的是奇异值. 3个相乘的形式可以拆分.即奇异值*第一行*第一列.在相加. 奇异值有时很小,在这种情况下,丢掉,可以减少计算 ...