cogs 1752 [BOI2007]摩基亚Mokia(cdq分治+树状数组)
数据范围过大,所以没有办法二维树状数组和二维线段树什么的。
听说kdtree可做?然而还不会。
这时候cdq分治就派上用场了,首先它不需要二维的空间,所有空间上是没问题的,然后时间复杂度也可以,具体时间复杂度分析下面再说。
这个问题其实可以看成一个三维偏序问题,(时间,横坐标,纵坐标)。
三维貌似看起来有些头疼,假如是二维呢,比如 问题是动态加点,询问一条线段里包含的权值和,
那样就是(时间,坐标)的一个二维偏序,对于我一个查询可以看成(a,b),(a,c)的两个偏序,a代表查询的时间,b,c代表线段的两个端点,那么我们如果找到时间小于a,坐标小于c的的权值和,再减去同样的比较方法小于(a,b)的权值和,不就求出了这一时刻这条线段里包含的权值和了嘛。
那么三维不就是把坐标扩大,按照求二维前缀和的方式去求容斥一下就好了?
我们需要先将一次询问转换为四次不同的二维前缀和查询操作,然后对于每一个询问,我们需要求出左区间(时间小于自己)里,横坐标小于自己纵坐标也小于自己的权值和,
时间已经满足,横坐标的话可以通过cdq分治时顺带的归并排序确定出横坐标小于自己的连续操作区间,但是纵坐标就需要用树状数组统计一下相应的权值了,在查询的时候再求出纵坐标小于自己的点的权值,每次分治的结束的时候都清空下树状数组,就做完了。
cdq分治递归logn层,每层o(n)的操作,然后加上一个树状数组的logn,时间复杂度就是nlog^nlog^2了。
cogs oj给出数据什么的真的好评,但是我数组开小了,应该re竟然返回wa了。
代码:
#include <stdio.h>//using namespace std;
const int maxn=2e6+5;
int ans[10005];
struct node
{int t;int x;int y;int qid;int val;int type;bool operator <(const node & a)const {return a.x==x?type<a.type:x<a.x;}
}que[maxn], tmp[maxn];
int n;int val[maxn];
int lowbit(int x)
{return x&-x;
}
void add(int x, int y)
{while(x<maxn){val[x]+=y;x+=lowbit(x);}return;
}int sum(int x)
{int res=0;while(x>0){res+=val[x];x-=lowbit(x);}return res;
}void cdq(int l, int r)
{if(r-l<=1)return;int mid=(l+r)>>1;cdq(l, mid);cdq(mid, r);int p=l, q=mid, o=0;
// printf("%d %d\n", l, r);while(p<mid && q<r){if(que[p]<que[q]){if(que[p].type==1){add(que[p].y, que[p].val);}tmp[o++]=que[p++];} else {if(que[q].type==2){ans[que[q].qid]+=que[q].val*sum(que[q].y);// printf("%d %d %d %d %d\n", que[q].x, que[q].y, que[q].val, que[q].qid, ans[que[q].qid]);}tmp[o++]=que[q++];}}while(q<r){if(que[q].type==2){ans[que[q].qid]+=que[q].val*sum(que[q].y);// printf("%d %d %d %d %d\n", que[q].x, que[q].y, que[q].val, que[q].qid, ans[que[q].qid]);}tmp[o++]=que[q++];}/*memset(val, 0, sizeof val);*/for(int i=l; i<p; i++)if(que[i].type==1)add(que[i].y, que[i].val*-1);while(p<mid){tmp[o++]=que[p++];}for(int i=0; i<o; i++)que[i+l]=tmp[i];return;
}int main()
{/*freopen("mokia.in", "r", stdin);freopen("mokia.out", "w", stdout);*/scanf("%*d%d", &n);int x, y, x1, y1, e, id=1, qid=1;while(~scanf("%d", &e)){if(e==3)break;if(e==1){scanf("%d%d%d", &que[id].x, &que[id].y, &que[id].val);que[id].t=id;que[id].type=1;} else {scanf("%d%d%d%d", &x, &y, &x1, &y1);que[id].t=id, que[id].x=x-1, que[id].y=y-1, que[id].val=1, que[id].qid=qid, que[id].type=2; id++;que[id].t=id, que[id].x=x-1, que[id].y=y1, que[id].val=-1, que[id].qid=qid, que[id].type=2; id++;que[id].t=id, que[id].x=x1, que[id].y=y-1, que[id].val=-1, que[id].qid=qid, que[id].type=2; id++;que[id].t=id, que[id].x=x1, que[id].y=y1, que[id].val=1, que[id].qid=qid, que[id].type=2; qid++;}id++;}cdq(1, id);for(int i=1; i<qid; i++){printf("%d\n", ans[i]);}
}
cogs 1752 [BOI2007]摩基亚Mokia(cdq分治+树状数组)相关推荐
- COJS 1752. [BOI2007]摩基亚Mokia
1752. [BOI2007]摩基亚Mokia ★★★ 输入文件:mokia.in 输出文件:mokia.out 简单对比 时间限制:5 s 内存限制:128 MB [题目描述] 摩尔 ...
- BZOJ 1176: [Balkan2007]Mokia( CDQ分治 + 树状数组 )
考虑cdq分治, 对于[l, r)递归[l, m), [m, r); 然后计算[l, m)的操作对[m, r)中询问的影响就可以了. 具体就是差分答案+排序+离散化然后树状数组维护.操作数为M的话时间 ...
- BZOJ - 2244 拦截导弹 (dp,CDQ分治+树状数组优化)
BZOJ - 2244 拦截导弹 (dp,CDQ分治+树状数组优化) 1 #include<algorithm> 2 #include<iostream> 3 #include ...
- P4093-[HEOI2016/TJOI2016]序列【CDQ分治,树状数组】
正题 题目链接:https://www.luogu.com.cn/problem/P4093 题目大意 nnn个数字,每次有一个数字可能和原序列不同,但最多只有一个不同. 求所有情况下都满足的最长不降 ...
- [cdq分治][树状数组] Bzoj P3262 陌上花开
Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),用三个整数表示. 现在要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量. 定义一朵花A比另一朵花B要美 ...
- 【COGS1752】 BOI2007—摩基亚Mokia
http://cogs.pro/cogs/problem/problem.php?pid=1752 (题目链接) 题意 给出$n*n$的棋盘,单点修改,矩阵查询. Solution 离线以后CDQ分治 ...
- CDQ分治 + 树状数组 ---- C. Goodbye Souvenir(三维偏序+思维)
题目链接 题目大意: 给定长度为nnn的数组, 定义数字XXX在[l,r][l,r][l,r]内的值为数字XXX在[l,r][l,r][l,r]内最后一次出现位置的下标减去第一次出现位置的下标 给定m ...
- Educational Codeforces Round 17 E. Radio stations cdq分治 + 树状数组
传送门 文章目录 题意 思路: 题意 有nnn个电台,对于每个电台iii有三个参数xi,ri,fix_i,r_i,f_ixi,ri,fi,分别指他们的坐标.作用半径.频率.如果两个电台频率差值在 ...
- P3157-[CQOI2011]动态逆序对【CDQ分治,树状数组】
正题 题目链接:https://www.luogu.com.cn/problem/P3157 题目大意 一个长度为nnn序列,每次删除一个数,求删除前的逆序对数量. 解题思路 时光倒流之后,我们变为每 ...
- P3810-[模板]三维偏序(陌上花开)【CDQ分治,树状数组】
正题 题目链接:https://www.luogu.com.cn/problem/P3810 题目大意 nnn个三元组(a,b,c)(a,b,c)(a,b,c),f(i)=∑i=1n,j≠i[aj≤a ...
最新文章
- 科大讯飞软件研发面试
- PhpStorm 对 AngularJS 的支持
- fckeditor编辑器自定义加按钮菜单
- Android之app引导页(背景图片切换加各个页面动画效果)
- Python中赋值,深拷贝和浅拷贝
- 易语言 取自定义数据类型的大小
- 艾迈斯半导体推出新款高性能读取IC,推动医疗和工业数字化X射线设备制造商降本增效
- RFID ACR-122U M1射频卡破解分析
- Java8 Lambda表达式的特快处理流Stream快速入门
- c++中的 trivial destructor
- 如何改变计算机桌面字体,怎么调整电脑桌面字体
- 智能管家项目总结(1)
- IOT数据采集的转换器的设计和实现
- 教你快速删除或/替换每个视频文件名中的空格、特殊符号
- 微信小程序导航头部吸顶效果
- CSDN博客的文字颜色、字体和字号设置
- Cmake语句find_package()函数
- 最大流问题与福特-富尔克森算法
- asp.net 下载EXCEL文件
- Python实现微信找茬小游戏自动进行