luoguP3769 [CH弱省胡策R2]TATT

PS:做这题前先切掉 P4148简单题,对于本人这样的juruo更助于理解,当然dalao就当练练手吧

题目大意: 现在有n个四维空间中的点,请求出一条最长的路径,满足任意一维坐标都是单调不降的

偏模板的K-D Tree

题目没规定起点,则从任意一点出发,按维度优先级以及每个维度坐标为关键字排序,

每点作为终点查询一次,再插入,其他就是模板化的代码了

这里用到了一个小技巧,就是初始化将子树0的值赋值,避免过多的特判,使代码更加简洁

for(LL i=0;i<=3;++i)
tree[0].mi[i]=inf,tree[0].mx[i]=-inf; tree[0].maxn=-inf;

My complete code:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long LL;
const LL maxn=1e5+10;
const LL inf=1e9;
inline LL read(){
LL x=0,f=1; char c=getchar();
while(c<'0'||c>'9'){
if(c=='-') f=-1; c=getchar();
}
while(c>='0'&&c<='9'){
x=x*10+c-'0'; c=getchar();
}
return x*f;
}
struct node{
LL son[2],d[4],maxn,size,val,mi[4],mx[4];
}tree[maxn],t2[maxn],tmp;
bool operator < (node g1,node g2){
for(LL i=0;i<=3;++i){
if(g1.d[i]<g2.d[i]) return 1;
if(g1.d[i]>g2.d[i]) return 0;
}return 0;
}
LL n,ans,ans_maxn,top,cnt,root,WD; LL sta[maxn];
inline void update(LL now){
LL son0=tree[now].son[0],son1=tree[now].son[1];
for(LL i=0;i<=3;++i){
tree[now].mi[i]=min(min(tree[son0].mi[i],tree[son1].mi[i]),tree[now].d[i]);
tree[now].mx[i]=max(max(tree[son0].mx[i],tree[son1].mx[i]),tree[now].d[i]);
}
tree[now].maxn=max(tree[now].val,max(tree[son0].maxn,tree[son1].maxn));
tree[now].size=tree[son0].size+tree[son1].size+1;
}
inline bool cmp(LL g1,LL g2){
return tree[g1].d[WD]<tree[g2].d[WD];
}
LL build(LL l,LL r,LL wd){
if(l>r)
return 0;
LL mid=(l+r)>>1;
WD=wd;
nth_element(sta+l,sta+mid,sta+r+1,cmp);
LL now=sta[mid];
tree[now].son[0]=build(l,mid-1,(wd+1)%4);
tree[now].son[1]=build(mid+1,r,(wd+1)%4);
update(now);
return now;
}
void pai(LL now){
if(!now)
return;
sta[++top]=now;
LL son0=tree[now].son[0],son1=tree[now].son[1];
pai(son0); pai(son1);
}
inline void check(LL &now,LL wd){
LL son0=tree[now].son[0],son1=tree[now].son[1];
if(tree[now].size*0.75<tree[son0].size||tree[now].size*0.75<tree[son1].size){
top=0;
pai(now);
now=build(1,tree[now].size,wd);
}
}
void insert(LL &now,LL wd){
if(!now){
now=++cnt;
tree[now]=tmp;
for(LL i=0;i<=3;++i)
tree[now].mi[i]=tree[now].mx[i]=tree[now].d[i];
tree[now].maxn=tree[now].val; tree[now].size=1;
return;
}
if(tmp.d[wd]<tree[now].d[wd])
insert(tree[now].son[0],(wd+1)%4);
else
insert(tree[now].son[1],(wd+1)%4);
update(now);
check(now,wd);
} inline LL dis(node g1,node g2){
for(LL i=0;i<=3;++i)
if(g1.d[i]>g2.d[i])
return 0;
return g1.val;
}
inline LL into(LL now){
if(!now)
return 0;
LL sum=0;
for(LL i=0;i<=3;++i)
if(tree[now].mx[i]<=tmp.d[i])
++sum;
if(sum==4)
return 4;
for(LL i=0;i<=3;++i)
if(tree[now].mi[i]>tmp.d[i])
return 0;
return 1;
}
void query(LL now){
ans=max(dis(tree[now],tmp),ans);
LL son0=tree[now].son[0],son1=tree[now].son[1];
LL dl=into(son0),dr=into(son1);
if(dl==4)
ans=max(tree[son0].maxn,ans);
else if(dl&&ans<tree[son0].maxn)
query(son0);
if(dr==4)
ans=max(tree[son1].maxn,ans);
else if(dr&&ans<tree[son1].maxn)
query(son1);
}
int main(){
n=read();
for(LL i=1;i<=n;++i){
for(LL j=0;j<=3;++j)
t2[i].d[j]=read();
t2[i].val=1;
}
sort(t2+1,t2+n+1);
for(LL i=0;i<=3;++i)
tree[0].mi[i]=inf,tree[0].mx[i]=-inf; tree[0].maxn=-inf;
for(LL i=1;i<=n;++i){
ans=0;
tmp=t2[i];
query(root);
tmp.val+=ans;
ans_maxn=max(tmp.val,ans_maxn);
insert(root,0);
}
printf("%lld",ans_maxn);
return 0;
}

  

luoguP3769 [CH弱省胡策R2]TATT的更多相关文章

  1. [CH弱省胡策R2]TATT

    description 洛谷 data range \[ n\le 5\times 10^4\] solution 这就是四维偏序了... 好象时间复杂度是\(O(n^{\frac{5}{3}})\) ...

  2. [Luogu3769][CH弱省胡策R2]TATT

    luogu 题意 其实就是四维偏序. sol 第一维排序,然后就只需要写个\(3D-tree\)了. 据说\(kD-tree\)的单次查询复杂度是\(O(n^{1-\frac{1}{k}})\).所以 ...

  3. 【题解】[CH弱省胡策R2]TATT

    本蒟蒻第一道\(K-D-Tree\)维护\(dp\) Question 题目大意:求一条路径,使得其四个维度单调不降. 先排序消掉一维再说. 对于每一个点,初始的时候绝对长度是1啊.于是,先赋值一个1 ...

  4. 洛谷3769[CH弱省胡策R2]TATT (KDTree)(四维LIS)

    真是一个自闭的题目(调了一个上午+大半个下午) 从\(WA\)到\(WA+TLE\)到\(TLE\)到\(AC\) 真的艰辛. 首先,这个题,我们可以考虑直接上四维KDTree来解决. 对于kdtre ...

  5. 【弱省胡策】Round #5 Count

    [弱省胡策]Round #5 Count 太神仙了. \(DP\)做法 设\(f_{n,m,d,k}\)表示\(n*m\)的矩阵,填入第\(k\)个颜色,并且第\(k\)个颜色最少的一列上有\(d\) ...

  6. 弱省胡策 Magic

    弱省胡策 Magic 求\(n\)个点\(n\)的条边的简单联通图的个数. 毒瘤,还要写高精. 我们枚举环的大小\(k\),\(\displaystyle ans=\sum_{k=3}^nC_n^k ...

  7. 【ContestHunter】【弱省胡策】【Round0】(A)&【Round1】(B)

    DP+容斥原理or补集转化?/KD-Tree 唔……突然发现最早打的两场(打的最烂的两场)没有写记录……(太烂所以不忍记录了吗... 还是把搞出来了的两道题记录一下吧= =勉强算弥补一下缺憾…… Ro ...

  8. 【ContestHunter】【弱省胡策】【Round3】(C)

    容斥原理+Fib Orz HE的神犇们 蒟蒻只能改出来第三题……实在太弱 官方题解:http://pan.baidu.com/s/1o6MdtQq fib的神奇性质……还有解密a[i]的过程……这里就 ...

  9. 【ContestHunter】【弱省胡策】【Round2】

    官方题解:http://wyfcyx.is-programmer.com/posts/95490.html A 目前只会30分的暴力……DP好像很神的样子0.0(听说可以多次随机强行算? //Roun ...

随机推荐

  1. apache服务器日志及重启方法

    进入  lamp安装目录 ./ctlscript.sh restart 重启 实时查看日志 tail -f error_log 查看日志方法  404 及某天的方法cat access_log_201 ...

  2. #pragma预处理命令【转】

    原文 : http://www.cnblogs.com/qinfengxiaoyue/archive/2012/06/05/2535524.html #pragma可以说是C++中最复杂的预处理指令了 ...

  3. C#遍历指定路径下的目录

    通过指定路径訪问路径下的文件.在C#的开发中主要利用了Directory类和DirectoryInfo类,简要介绍Directory类中的成员:命名空间 System.IO 命名空间 1.Create ...

  4. sublime添加sass编译

    首先安装Ruby环境sass是基于ruby的产物,因此在安装sass前需要先安装ruby,如果用命令方式编译Sass也是必须安装ruby的.命令行编译sass见!下载Ruby windows 安装包: ...

  5. 文件I/O之C标准库函数和系统库函数差别

    1.首先C标准库函数是工作在系统库函数之上的.C标准库函数在读写文件时候都有一个文件流指针.FILE*fp=NULL;// fp=fopen(F_PATH,"r"); fp文件流指 ...

  6. iOS多线程与网络开发之小文件上传

    郝萌主倾心贡献,尊重作者的劳动成果,请勿转载. /** 取得本地文件的MIMEType */ 2 - (void) getMIMEType { 3 // Socket 实现断点上传 4 5 //apa ...

  7. Selenium详解

    自动化测试工具,支持多种浏览器.爬虫中主要用来解决JavaScript渲染的问题. 主要是操控流量器,让浏览器做一些点击啊.加载渲染js啊,之类的.

  8. wpf SplitButton

     SplitButton该控件除了本身Button 的功能外,还具有下拉菜单的功能,能够在按键右側加入下拉菜单控件: <SplitButton Content="..." ...

  9. android开发系列之使用xml自定义控件

    在android开发的过程中,有的时候面对多个Activity里面一些相同的布局,我们需要写多次相同的代码,同时这种方法给我们的项目维护也带来了很大不便.那么有没有一种可行的办法能够将Activity ...

  10. Chrome + Python 抓取动态网页内容

    用Python实现常规的静态网页抓取时,往往是用urllib2来获取整个HTML页面,然后从HTML文件中逐字查找对应的关键字.如下所示: import urllib2 url="http: ...