BZOJ.3262.陌上花开([模板]CDQ分治 三维偏序)
/*
5904kb 872ms
对于相邻x,y,z相同的元素要进行去重,并记录次数算入贡献(它们之间产生的答案是一样的,但不去重会。。)
*/
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
#define lb(x) (x)&-(x)
const int N=1e5+5;
int n,Ans[N];
int read();
struct Operation
{
int x,y,z,cnt,res;
inline void Init(){
x=read(),y=read(),z=read(),cnt=1;
}
bool operator <(const Operation &a)const{
return x==a.x?(y==a.y?z<a.z:y<a.y):x<a.x;
}
}q[N],tmp[N];
namespace BIT
{//三维:树状数组
int Max,t[N<<1];
void Add(int p,int v){
while(p<=Max) t[p]+=v,p+=lb(p);
}
int Query(int p){
int res=0;
while(p) res+=t[p],p-=lb(p);
return res;
}
}
inline int read()
{
int now=0,f=1;register char c=gc();
for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now*f;
}
void CDQ(int l,int r)
{//处理第二维
if(l<r)
{
int m=l+r>>1; CDQ(l,m), CDQ(m+1,r);
int p1=l,p2=m+1,cnt=0;
while(p1<=m&&p2<=r)
{
if(q[p1].y<=q[p2].y)//这里的条件要是<=
BIT::Add(q[p1].z,q[p1].cnt), tmp[cnt++]=q[p1++];
else
q[p2].res+=BIT::Query(q[p2].z), tmp[cnt++]=q[p2++];
}
while(p1<=m) BIT::Add(q[p1].z,q[p1].cnt), tmp[cnt++]=q[p1++];//先加上 方便再减去
while(p2<=r) q[p2].res+=BIT::Query(q[p2].z), tmp[cnt++]=q[p2++];
for(int i=l; i<=m; ++i) BIT::Add(q[i].z,-q[i].cnt);
for(int i=0; i<cnt; ++i) q[l+i]=tmp[i];
}
}
int main()
{
n=read(),BIT::Max=read();
for(int i=1; i<=n; ++i) q[i].Init();
std::sort(q+1,q+1+n);
int cnt=1;
for(int i=2; i<=n; ++i)
if(q[i].x==q[i-1].x&&q[i].y==q[i-1].y&&q[i].z==q[i-1].z) ++q[cnt].cnt;
else q[++cnt]=q[i];
CDQ(1,cnt);
for(int i=1; i<=cnt; ++i) Ans[q[i].res+q[i].cnt-1]+=q[i].cnt;//f[i]为res[i]+cnt[i]-1, 贡献为cnt[i]
for(int i=0; i<n; ++i) printf("%d\n",Ans[i]);
return 0;
}
18.3.30:
/*
5904kb 840ms
是对x,y,z都相同的元素去重,不是对z。。sb了。
去重后的贡献是q[p].cnt!
*/
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
#define lb(x) (x)&-(x)
const int N=1e5+5,MAXN=2e5+5;
int n,Ans[N];
int read();
struct Node
{
int x,y,z,cnt,ans;
void Init(){
x=read(),y=read(),z=read(),cnt=1;
}
bool operator <(const Node &a)const{
return x==a.x?(y==a.y?z<a.z:y<a.y):x<a.x;
}
}q[N],tmp[N];
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
namespace BIT
{
int n,val[MAXN];
inline void Add(int p,int v){
while(p<=n) val[p]+=v,p+=lb(p);
}
inline int Query(int p){
int res=0;
while(p) res+=val[p],p-=lb(p);
return res;
}
inline void Clear(int p){
while(p<=n)
if(val[p]) val[p]=0,p+=lb(p);
else break;
}
}
void CDQ(int l,int r)
{
if(l<r){
int m=l+r>>1; CDQ(l,m), CDQ(m+1,r);
int p1=l,p2=m+1,t=0;
while(p1<=m&&p2<=r)
{
if(q[p1].y<=q[p2].y) BIT::Add(q[p1].z,q[p1].cnt), tmp[t++]=q[p1++];//只是排y,别去管什么z。。
else q[p2].ans+=BIT::Query(q[p2].z), tmp[t++]=q[p2++];
}
if(p1<=m){
for(int i=l; i<p1; ++i) BIT::Clear(q[i].z);
while(p1<=m) tmp[t++]=q[p1++];
}
else if(p2<=r){
while(p2<=r) q[p2].ans+=BIT::Query(q[p2].z), tmp[t++]=q[p2++];
for(int i=l; i<=m; ++i) BIT::Clear(q[i].z);
}
for(int i=0; i<t; ++i) q[l+i]=tmp[i];
}
}
int main()
{
n=read(),BIT::n=read();
for(int i=1; i<=n; ++i) q[i].Init();
std::sort(q+1,q+1+n);
int cnt=1;
for(int i=2; i<=n; ++i)
if(q[i].z!=q[i-1].z||q[i].y!=q[i-1].y||q[i].x!=q[i-1].x) q[++cnt]=q[i];
else ++q[cnt].cnt;
CDQ(1,cnt);
for(int i=1; i<=cnt; ++i) Ans[q[i].ans+q[i].cnt-1]+=q[i].cnt;
for(int i=0; i<n; ++i) printf("%d\n",Ans[i]);
return 0;
}
19.4.5
上BZOJ前三啦。
//6196KB 688MS
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
#define MAXIN 300000
//#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
typedef long long LL;
const int N=1e5+5,M=2e5+5;
int Ans[N];
char IN[MAXIN],*SS=IN,*TT=IN;
struct Node
{
int x,y,z,cnt,ans;
bool operator <(const Node &a)const
{
return x==a.x?(y==a.y?z<a.z:y<a.y):x<a.x;
}
bool operator !=(const Node &a)const
{
return x!=a.x||y!=a.y||z!=a.z;
}
}q[N],tmp[N];
struct BIT
{
int n,t[M];//M!
#define lb(x) (x&-x)
inline void Add(int p,int v)
{
for(; p<=n; p+=lb(p)) t[p]+=v;
}
inline int Query(int p)
{
int res=0;
for(; p; p^=lb(p)) res+=t[p];
return res;
}
inline void Clear(int p)
{
for(; p<=n&&t[p]; p+=lb(p)) t[p]=0;
}
}T;
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-48,c=gc());
return now;
}
void CDQ(int l,int r)
{
if(l<r)
{
int m=l+r>>1; CDQ(l,m), CDQ(m+1,r);
int p1=l,p2=m+1,p=l;
while(p1<=m&&p2<=r)
{
if(q[p1].y<=q[p2].y) T.Add(q[p1].z,q[p1].cnt), tmp[p++]=q[p1++];//q[p1].cnt!
else q[p2].ans+=T.Query(q[p2].z), tmp[p++]=q[p2++];
}
while(p2<=r) q[p2].ans+=T.Query(q[p2].z), tmp[p++]=q[p2++];
for(int i=l; i<p1; ++i) T.Clear(q[i].z);//<p1
while(p1<=m) tmp[p++]=q[p1++];
for(int i=l; i<=r; ++i) q[i]=tmp[i];
}
}
int main()
{
int n=read(); T.n=read();
for(int i=1; i<=n; ++i) q[i]=(Node){read(),read(),read(),1,0};//cnt不能是0啊= =
std::sort(q+1,q+1+n); int cnt=1;
for(int i=2; i<=n; ++i)
if(q[i]!=q[i-1]) q[++cnt]=q[i];
else ++q[cnt].cnt;
CDQ(1,cnt);
for(int i=1; i<=cnt; ++i) Ans[q[i].ans+q[i].cnt-1]+=q[i].cnt;
for(int i=0; i<n; ++i) printf("%d\n",Ans[i]);
return 0;
}
BZOJ.3262.陌上花开([模板]CDQ分治 三维偏序)的更多相关文章
- bzoj 3262 陌上花开 【CDQ分治】
三维偏序 首先把所有花按 x一序,y二序,z三序 排序,然后去重,con记录同样的花的个数,然后进行cdq 现在假设有[l.r]区间,其中[l,mid] [mid+1,r],已经递归处理完毕.我们把区 ...
- BZOJ 3262: 陌上花开 [CDQ分治 三维偏序]
Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当 ...
- [bzoj] 3263 陌上花开 洛谷 P3810 三维偏序|| CDQ分治 && CDQ分治讲解
原题 定义一个点比另一个点大为当且仅当这个点的三个值分别大于等于另一个点的三个值.每比一个点大就为加一等级,求每个等级的点的数量. 显然的三维偏序问题,CDQ的板子题. CDQ分治: CDQ分治是一种 ...
- 洛谷P3810 陌上花开 CDQ分治(三维偏序)
好,这是一道三维偏序的模板题 当然没那么简单..... 首先谴责洛谷一下:可怜的陌上花开的题面被无情的消灭了: 这么好听的名字#(滑稽) 那么我们看了题面后就发现:这就是一个三维偏序.只不过ans不加 ...
- 【BZOJ 3262】 3262: 陌上花开 (CDQ分治)
3262: 陌上花开 Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A ...
- BZOJ 2244: [SDOI2011]拦截导弹 (CDQ分治 三维偏序 DP)
题意 略- 分析 就是求最长不上升子序列,坐标取一下反就是求最长不下降子序列,比较大小是二维(h,v)(h,v)(h,v)的比较.我们不看概率,先看第一问怎么求最长不降子序列.设f[i]f[i]f[i ...
- cdq分治·三维偏序问题
转载自FlashHu大佬的博客CDQ分治总结(CDQ,树状数组,归并排序),在讲述部分有部分删改,用了自己的代码 CDQ分治的思想 CDQ分治是基于时间的离线分治算法.这一类分治有一个重要的思想——用 ...
- NEUOJ 1702:撩妹全靠魅力值(CDQ分治三维偏序)
http://acm.neu.edu.cn/hustoj/problem.php?id=1702 思路:三维偏序模板题,用CDQ分治+树状数组或者树套树.对于三元组(x,y,z),先对x进行排序,然后 ...
- 【算法】CDQ分治 -- 三维偏序 & 动态逆序对
初次接触CDQ分治,感觉真的挺厉害的.整体思路即分而治之,再用之前处理出来的答案统计之后的答案. 大概流程是(对于区间 l ~ r): 1.处理 l ~mid, mid + 1 ~ r 的答案: 2. ...
随机推荐
- js的正则表达式编程,悬赏解决下面的问题
悬赏解决下面的问题 1.切分url 2.将时间日期 转化为 yyyy-MM-dd的模式和可逆性 3.数据的千分位和可逆性 4.用C#或者nodejs检索如下的模式 h1{ border:1px sol ...
- 【Python】Python-基础语法学习
基础语法学习 果然学完 C++ 后再看其他语言的确有很多的共性,只需要熟悉一下python的独特语法和 C++ 中的差异就可以写出一些小的程序,而写得过程中也再次体会出python代码的精简和灵活: ...
- Linux内核调试方法【转】
转自:http://www.cnblogs.com/shineshqw/articles/2359114.html kdb:只能在汇编代码级进行调试: 优点是不需要两台机器进行调试. gdb:在调试模 ...
- Innodb ,MyISAM
1. InnoDB不支持FULLTEXT类型的索引. 2. InnoDB 中不保存表的具体行数,也就是说,执行select count(*) from table时,InnoDB要扫描一遍整个表来计算 ...
- zabbix3.0监控centos当主机cpu使用率超过90%的时候报警
在windows系统中监控cpu利用率非常容易,自带模板就有这样的功能,但是在linux里面没有默认的模板 只有cpu的负载,默认当cpu的负载在一定时间内5以上报警 cpu utilization中 ...
- 网站遭遇CC及DDOS攻击紧急处理方案
检测访问是否是CC攻击的命令: 80口为网站的访问端口,可以根据实际情况进行修改 # netstat -anlp|grep 80|grep tcp|awk '{print $5}'|awk -F: ' ...
- 通达OA批量处理没有结束但前台显示已经结束的流程
问题描述: 通达OA系统出现大量流程没有结束,系统显示结束的问题 通过查询操作系统日志,数据库日志,包括程序日志没有发现异常,通过观察发现大量的流程结束时间都是在2016-02-16 17:32:XX ...
- 浏览器桌面通知Notification实践
一言不合就上图: 最近常常在浏览器看到这样的消息推送,还有QQ.com的推送,现在我对这个不了解,不知道叫消息自动推送对不对,这个时chrome浏览器的截图,出现在右下角,其他浏览器的样式可能有些微差 ...
- PHP实现获取文件后缀名的几种常用方法
方法1: function get_file_type($filename){ $type = substr($filename, strrpos($filename, ".")+ ...
- poj2342 没有上司的舞会 树形dp基础
#include<iostream> #include<cstring> #include<cstdio> #include<vector> using ...