【CJOJ2616】 【HZOI 2016】偏序 I(cdq分治,树状数组)
传送门
Solution
考虑这是一个四维偏序对吧。
直接cdq套在一起,然后这题有两种实现方法(树状数组的更快!)
代码实现1(cdq+cdq+cdq)
/*
mail: mleautomaton@foxmail.com
author: MLEAutoMaton
This Code is made by MLEAutoMaton
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<iostream>
using namespace std;
#define ll long long
#define re register
#define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
inline int gi()
{
int f=1,sum=0;char ch=getchar();
while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
return f*sum;
}
const int N=100010;
struct node
{
int a,b,c,opt1,opt2;
}a[N<<1],tmp1[N],tmp2[N],tmp3[N];
int n,ans;
void cdq3(int,int);
void cdq2(int,int);
void cdq1(int,int);
int main()
{
n=gi();
for(int i=1;i<=n;i++)a[i].a=gi();
for(int i=1;i<=n;i++)a[i].b=gi();
for(int i=1;i<=n;i++)a[i].c=gi();
cdq1(1,n);
printf("%d\n",ans);
return 0;
}
void cdq1(int l,int r)
{
if(l==r)return;
int mid=(l+r)>>1;
cdq1(l,mid);cdq1(mid+1,r);
int tot=l-1;int L=l,R=mid+1;
while(L<=mid && R<=r)
{
if(a[L].a<a[R].a){a[L].opt1=0;tmp1[++tot]=a[L++];}
else{a[R].opt1=1;tmp1[++tot]=a[R++];}
}
while(L<=mid){a[L].opt1=0;tmp1[++tot]=a[L++];}
while(R<=r){a[R].opt1=1;tmp1[++tot]=a[R++];}
for(int i=l;i<=r;i++)a[i]=tmp1[i];
cdq2(l,r);
}
void cdq2(int l,int r)
{
if(l==r)return;
int mid=(l+r)>>1;
cdq2(l,mid);cdq2(mid+1,r);
int tot=l-1;int L=l,R=mid+1;
while(L<=mid && R<=r)
{
if(tmp1[L].b<tmp1[R].b){tmp1[L].opt2=0;tmp2[++tot]=tmp1[L++];}
else{tmp1[R].opt2=1;tmp2[++tot]=tmp1[R++];}
}
while(L<=mid){tmp1[L].opt2=0;tmp2[++tot]=tmp1[L++];}
while(R<=r){tmp1[R].opt2=1;tmp2[++tot]=tmp1[R++];}
for(int i=l;i<=r;i++)tmp1[i]=tmp2[i];
cdq3(l,r);
}
void cdq3(int l,int r)
{
if(l==r)return;
int mid=(l+r)>>1;
cdq3(l,mid);cdq3(mid+1,r);
int tot=l-1;int L=l,R=mid+1,cnt=0;
while(L<=mid && R<=r)
{
if(tmp2[L].c<tmp2[R].c){if((tmp2[L].opt1|tmp2[L].opt2)==0)cnt++;tmp3[++tot]=tmp2[L++];}
else{if((tmp2[R].opt1&tmp2[R].opt2)==1)ans+=cnt;tmp3[++tot]=tmp2[R++];}
}
while(R<=r){if((tmp2[R].opt1&tmp2[R].opt2)==1)ans+=cnt;tmp3[++tot]=tmp2[R++];}
while(L<=mid)tmp3[++tot]=tmp2[L++];
for(int i=l;i<=r;i++)tmp2[i]=tmp3[i];
}
代码实现2(cdq+cdq+BIT)
/*
mail: mleautomaton@foxmail.com
author: MLEAutoMaton
This Code is made by MLEAutoMaton
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<iostream>
using namespace std;
#define ll long long
#define re register
#define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
inline int gi()
{
int f=1,sum=0;char ch=getchar();
while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
return f*sum;
}
const int N=100010;
struct node
{
int a,b,c,opt;
}a[N<<1],tmp1[N],tmp2[N];
int n,tot,ans,c[N];
int lowbit(int x){return x&(-x);}
void Add(int x,int d){while(x<=n){c[x]+=d;x+=lowbit(x);}}
int query(int x){int ret=0;while(x){ret+=c[x];x-=lowbit(x);}return ret;}
void cdq2(int,int);
void cdq1(int,int);
int main()
{
n=gi();
for(int i=1;i<=n;i++)a[i].a=gi();
for(int i=1;i<=n;i++)a[i].b=gi();
for(int i=1;i<=n;i++)a[i].c=gi();
cdq1(1,n);
printf("%d\n",ans);
return 0;
}
void cdq1(int l,int r)
{
if(l==r)return;
int mid=(l+r)>>1;
cdq1(l,mid);cdq1(mid+1,r);
tot=l-1;int L=l,R=mid+1;
while(L<=mid && R<=r)
{
if(a[L].a<a[R].a){a[L].opt=0;tmp1[++tot]=a[L++];}
else{a[R].opt=1;tmp1[++tot]=a[R++];}
}
while(L<=mid){a[L].opt=0;tmp1[++tot]=a[L++];}
while(R<=r){a[R].opt=1;tmp1[++tot]=a[R++];}
for(int i=l;i<=r;i++)a[i]=tmp1[i];
cdq2(l,r);
}
void cdq2(int l,int r)
{
if(l==r)return;
int mid=(l+r)>>1;
cdq2(l,mid);cdq2(mid+1,r);
int L=l,R=mid+1;tot=0;
while(L<=mid && R<=r)
{
if(tmp1[L].b<tmp1[R].b)
{
tmp2[++tot]=tmp1[L];
if(!tmp1[L].opt)Add(tmp1[L].c,1);
L++;
}
else
{
tmp2[++tot]=tmp1[R];
if(tmp1[R].opt)ans+=query(tmp1[R].c);
R++;
}
}
while(R<=r)
{
tmp2[++tot]=tmp1[R];
if(tmp1[R].opt)ans+=query(tmp1[R].c);
R++;
}
for(int i=l;i<L;i++)if(!tmp1[i].opt)Add(tmp1[i].c,-1);
while(L<=mid){tmp2[++tot]=tmp1[L];L++;}
for(int i=l;i<=r;i++)tmp1[i]=tmp2[i-l+1];
}
【CJOJ2616】 【HZOI 2016】偏序 I(cdq分治,树状数组)的更多相关文章
- LOJ3146 APIO2019路灯(cdq分治+树状数组)
每个时刻都形成若干段满足段内任意两点可达.将其视为若干正方形.则查询相当于求历史上某点被正方形包含的时刻数量.并且注意到每个时刻只有O(1)个正方形出现或消失,那么求出每个矩形的出现时间和消失时间,就 ...
- 【BZOJ4553】[Tjoi2016&Heoi2016]序列 cdq分治+树状数组
[BZOJ4553][Tjoi2016&Heoi2016]序列 Description 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他.玩具上有一个数列,数列中某些项的值可能 ...
- 【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 ...
- BZOJ 1176 Mokia CDQ分治+树状数组
1176: [Balkan2007]Mokia Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 1854 Solved: 821[Submit][St ...
- 【bzoj3262】陌上花开 CDQ分治+树状数组
题目描述 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当且仅当Sa&g ...
- BZOJ 2683 简单题 cdq分治+树状数组
题意:链接 **方法:**cdq分治+树状数组 解析: 首先对于这道题,看了范围之后.二维的数据结构是显然不能过的.于是我们可能会考虑把一维排序之后还有一位上数据结构什么的,然而cdq分治却可以非常好 ...
- bzoj 3262 陌上花开 - CDQ分治 - 树状数组
Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当 ...
- BZOJ 4553 [Tjoi2016&Heoi2016]序列 ——CDQ分治 树状数组
考虑答案的构成,发现是一个有限制条件的偏序问题. 然后三个维度的DP,可以排序.CDQ.树状数组各解决一维. #include <map> #include <cmath> # ...
- BZOJ3262陌上花开(三维偏序问题(CDQ分治+树状数组))+CDQ分治基本思想
emmmm我能怎么说呢 CDQ分治显然我没法写一篇完整的优秀的博客,因为我自己还不是很明白... 因为这玩意的思想实在是太短了: fateice如是说道: 如果说对于一道题目的离线操作,假设有n个操作 ...
- hdu_4742_Pinball Game 3D(cdq分治+树状数组)
题目链接:hdu_4742_Pinball Game 3D 题意: 给你n个点,让你求三维的LIS,并且求出有多少种组合能达到LIS. 题解: 求三维的LIS,典型的三维偏序问题,x排序,解决一维,c ...
随机推荐
- java的nio例子
package main; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.net.Inet ...
- 之前的一些Oracle的经验总结
1. 安装: 1) 关于字符集的选择,现在还不很了解,修改是需要进入一个模式下才可以修改,当然新建一个数据库实例的时候可以重新设定: UTF8是相对比较大的一个字符集, 可以简单实用这个就能保存很多的 ...
- 嵌入式操作系统VxWorks中网络协议存储池原理及实现
嵌入式操作系统VxWorks中网络协议存储池原理及实现 周卫东 蔺妍 刘利强 (哈尔滨工程大学自动化学院,黑龙江 哈尔滨,150001) 摘 要 本文讨论了网络协议存储池的基本原理和在嵌入式操作系 ...
- UVa 11762 Race to 1 (数学期望 + 记忆化搜索)
题意:给定一个整数 n ,然后你要把它变成 1,变换操作就是随机从小于等于 n 的素数中选一个p,如果这个数是 n 的约数,那么就可以变成 n/p,否则还是本身,问你把它变成 1 的数学期望是多少. ...
- 判断页面是app打开还是浏览器打开。cookie
有个需求需要对页面判断不同的打开方式来最里面的链接进行不同调整, 这样就要分四种情况,app,浏览器X安卓系统,苹果系统,起初是对页面url地址带有的参数(安卓)跟用户代理(苹果)返回值判断navig ...
- gcc和vs在c的一些区别
1.switch中每个标签后面的命令在gcc中需要{}括起来以指明作用域. 2._itoa是非标准的c和c++扩展函数,在linux下可以使用sprintf(string, "%d &q ...
- 20169207《Linux内核原理及分析》第十三周作业
第一周作业::对Linux的基本知识进行了了解,并对基本操作进行熟悉和应用. 第二周作业::了解了冯诺依曼体系结构.各种寄存器的功能和汇编指令的作用和功能. 第三周作业::这周主要了解了Linux系统 ...
- CentOS 5 上配置 Redmine 和 Git
现在我们用 Trac + Git 来管理所有的项目,早些时候是由 Trac + Subversion 管理的,和 Git 比较起来 Subversion 简直就是龟速.虽然我们前段时间换成了 Git ...
- noip第2课作业
1. 大象喝水 [问题描述] 一只大象口渴了,要喝20升水才能解渴,但现在只有一个深h厘米,底面半径为r厘米的小圆桶(h和r都是整数).问大象至少要喝多少桶水才会解渴. 输入:输入有一行,包行两 ...
- Eclipse运行wordcount步骤
Eclipse运行wordcount步骤 第一步:建立工程,导入代码. 第二步:建立文件写入数据(以空格分开),并上传到hdfs上. 1.创建文件并写入数据: 2.上传hdfs 在hadoop权限下就 ...