cdq分治入门--BZOJ3262: 陌上花开
n<=100000个人,每个人三个属性Ai,Bi,Ci,一个人i的等级为Ai>=Aj,Bi>=Bj,Ci>=Cj的人数,求每个等级有多少人。
裸的三维偏序。按照常规思路,一维排序,一维归并,一维利用单调性或用树状数组维护,这里选择后者。
先按Ai排序,然后在分治过程中,solve(l,mid),solve(mid+1,r),然后考虑(l,mid)对(mid+1,r)答案的贡献,先把这两部分分别按B排序,然后两个指针一起扫,扫的过程中,把C的值作下标丢进树状数组,查询时相当于树状数组前缀和。
思路很好,可样例过不了。
原因:在计算过程中默认后面对前面是没有贡献的,但按Ai排序后,相同的Ai值可能引起后面对前面的贡献。
方法:保证后面对前面无贡献,一开始就先按A再按B最后按C排序即可。
那还有重复的呢?去重呗!
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
//#include<iostream>
using namespace std; int n,m;
#define maxn 200011
int ord[maxn],tmpord[maxn];
struct BIT
{
int a[maxn];
BIT() {memset(a,,sizeof(a));}
void add(int x,int v) {for (;x<=n;x+=x&-x) a[x]+=v;}
int query(int x) {int ans=;for (;x;x-=x&-x) ans+=a[x];return ans;}
}t; struct Point
{
int x,y,z,cnt;
bool operator < (const Point &b) const
{return x<b.x || (x==b.x && y<b.y) || (x==b.x && y==b.y && z<b.z);}
}q[maxn],p[maxn];
int ans[maxn],ansnum[maxn];
void solve(int L,int R)
{
if (L==R) {ans[L]+=p[L].cnt-;ord[L]=L;return;}
const int mid=(L+R)>>;
solve(L,mid);
solve(mid+,R);
int i=L,j=mid+,k=L;
while (i<=mid && j<=R)
{
if (p[ord[i]].y<=p[ord[j]].y)
{
tmpord[k++]=ord[i];
t.add(p[ord[i]].z,p[ord[i]].cnt);
i++;
}
else
{
tmpord[k++]=ord[j];
ans[ord[j]]+=t.query(p[ord[j]].z);
j++;
}
}
for (;j<=R;j++) ans[ord[j]]+=t.query(p[ord[j]].z),tmpord[k++]=ord[j];
for (int ii=L;ii<i;ii++) t.add(p[ord[ii]].z,-p[ord[ii]].cnt);
for (;i<=mid;i++) tmpord[k++]=ord[i];
for (int x=L;x<=R;x++) ord[x]=tmpord[x];
} int lisan[maxn];
int main()
{
scanf("%d%d",&n,&m);
for (int i=;i<=n;i++)
{
scanf("%d%d%d",&q[i].x,&q[i].y,&q[i].z);
lisan[i]=q[i].z;
}
sort(lisan+,lisan++n);
for (int i=;i<=n;i++) q[i].z=lower_bound(lisan+,lisan++n,q[i].z)-lisan;
sort(q+,q++n);
int tot=;q[].x=-0x3f3f3f3f;
for (int i=;i<=n;i++)
{
if (q[i-].x==q[i].x && q[i-].y==q[i].y && q[i-].z==q[i].z) p[tot].cnt++;
else p[++tot]=q[i],p[tot].cnt=;
}
solve(,tot);
for (int i=;i<=tot;i++) ansnum[ans[i]]+=p[i].cnt;
for (int i=;i<n;i++) printf("%d\n",ansnum[i]);
return ;
}
cdq分治入门--BZOJ3262: 陌上花开的更多相关文章
- CDQ分治入门 + 例题 Arnooks's Defensive Line [Uva live 5871]
CDQ分治入门 简介 CDQ分治是一种特别的分治方法,它由CDQ(陈丹琦)神犇于09国家集训队作业中首次提出,因此得名.CDQ分治属于分治的一种.它一般只能处理非强制在线的问题,除此之外这个算法作为某 ...
- bzoj3262陌上花开 cdq分治入门题
Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当 ...
- 【学术篇】bzoj3262 陌上花开. cdq分治入门
花儿们已经很累了-- 无论是花形.颜色.还是气味, 都不是为了给人们摆出来欣赏的, 更不是为了当做出题的素材的, 她们并不想自己这些属性被没有生命的数字量化, 并不想和其它的花攀比, 并无意分出个三六 ...
- CDQ分治入门
前言 \(CDQ\)分治是一个神奇的算法. 它有着广泛的用途,甚至在某些题目中还能取代\(KD-Tree\).树套树等恶心的数据结构成为正解,而且常数还小得多. 不过它也有一定的缺点,如必须离线操作, ...
- COGS 577 蝗灾 [CDQ分治入门题]
题目链接 昨天mhr神犇,讲分治时的CDQ分治的入门题. 题意: 你又一个w*w正方形的田地. 初始时没有蝗虫. 给你两个操作: 1. 1 x y z: (x,y)这个位置多了z只蝗虫. 2. 2 x ...
- cdq分治入门学习 cogs 1752 Mokia nwerc 2015-2016 G 二维偏序
/* CDQ分治的对象是时间. 即对于一个时间段[L, R],我们取mid = (L + R) / 2. 分治的每层只考虑mid之前的修改对mid之后的查询的贡献,然后递归到[L,mid],(mid, ...
- cdq分治入门and持续学习orz
感觉cdq分治是一个很有趣的算法 能将很多需要套数据结构的题通过离线来做 目前的一些微小的理解 在一般情况下 就像求三维偏序xyz 就可以先对x排序 然后分治 1 cdq_x(L,M) ; 2 提取出 ...
- caioj1097: [视频]树状数组1(快速求和计算) cdq分治入门
这题虽然是个树状数组,但是也可以用cdq分治做啊~~,这个就是一个浅显的二维偏序的应用? cdq分治和普通的分治有什么区别? 举个栗子:有4个小朋友,你请他们吃饭,假如你分治搞,就会分成很多子问题—— ...
- cdq分治入门--BZOJ1492: [NOI2007]货币兑换Cash
n<=100000天,一开始有s块钱,每天股票A价格ai,B价格bi,每天可以做的事情:卖出股票:按A:B=RTi的比例买入股票.问最后的最大收益.股票可以为浮点数,答案保留三位. 用脚指头想想 ...
随机推荐
- div 弹出 居中
function show_tc_conv(){var x=jq13(window).width()/2;var y=jq13(window).height()/2; var div_w=jq13(& ...
- SQLServer 2012 高效分页
SQLSERVER2012 出新分页功能啦!!!近两天我在自己工作机的PC(没有并发,单一线程)上做了SqlServer 2000/ (2005/2008)/2012三个版本下的分页性能比较. 大致 ...
- 【Hibernate】多对多关系的表达
User.hbm.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate ...
- [BZOJ2190][SDOI2008]仪仗队 数学
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2190 看到这道题首先想到了NOI2010的能量采集,这不就是赤裸裸的弱化版吗?直接上莫比乌 ...
- 使用一个CSS Class去给标签定义Style
使用一个CSS Class去给标签定义Style 类是可重用的样式,可以添加到HTML元素. 下面是一个CSS类声明的例子: <style> .blue-text { colo ...
- windows测试物理网络
ping 192.168.10.88 -t ,参数-t是等待用户去中断测试
- cce - 控制台中文环境
语法 (SYNTAX) cce [-e program] 描述 (DESCRIPTION) 该程序是一个类似于 WZCE , yact 和 chdrv 的控制台中文平台.进入该环境后可以用“空格 + ...
- 使用GetLogicalDrives获取卷标
#include<stdio.h> #include<windows.h> int main() { DWORD dwLogical= GetLogicalDrives(); ...
- console.log()与console.dir()
console.log()可以取代alert()或document.write(),在网页脚本中使用console.log()时,会在浏览器控制台打印出信息. console.dir()可以显示一个对 ...
- 15数据库与ADO.Net
数据库与ADO.Net 数据库与ADO.Net 8.1 数据库基本概念 数据库提供了一种将信息集合在一起的方法.数据库应用系统主要由三部分组成:数据库管理系统(DBMS),是针对所有应用的,例如A ...