博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
洛谷3769[CH弱省胡策R2]TATT (KDTree)(四维LIS)
阅读量:5270 次
发布时间:2019-06-14

本文共 3724 字,大约阅读时间需要 12 分钟。

真是一个自闭的题目(调了一个上午+大半个下午)

\(WA\)\(WA+TLE\)\(TLE\)\(AC\)

真的艰辛。

首先,这个题,我们可以考虑直接上四维KDTree来解决。

对于kdtree上的每个节点,我们维护三个值,分别表示各个维度的\(mn\),当前节点的\(val\)(这个是用来每次更新\(ans\)的),子树的\(val\)的最大值(用来做估价函数)

首先\(build\)出整个kdtree

void up(int root){    for (int i=0;i<=3;i++)    {     if (t[root].l)          t[root].mn[i]=min(t[root].mn[i],t[t[root].l].mn[i]);        if (t[root].r)          t[root].mn[i]=min(t[root].mn[i],t[t[root].r].mn[i]);    }    t[root].val=max(t[root].cao,max(t[t[root].l].val,t[t[root].r].val));}void build(int &x,int l,int r,int fa,int dd){    ymh = dd;    int mid = l+r >> 1;    dd++;    if (dd==4) dd=0;    x = mid;    nth_element(t+l,t+x,t+r+1);     t[x].fa=fa;    t[x].cao=0;    for (int i=0;i<=3;i++) t[x].mn[i]=t[x].d[i];    back[t[x].num]=x;    if (l

然后,我们用kdtree来维护一个做lis的过程

其中,我们先对所有点进行排序,然后依次枚举他们。

对于一次\(query\),我们首先\(check\)一下当前点能不能更新\(ans\),然后通过子树max来估价,判断先进入哪个子树,或者进不进入当前子树

bool get(KD a,KD b){    for (int i=0;i<=3;i++)      if (a.d[i]>b.d[i]) return 0;    return 1;}int calc(int x,KD b){    if (!x) return 0;    for (int i=0;i<=3;i++)      if (t[x].mn[i]>b.d[i]) return 0;    return 1;}void query(int x,KD caonima,int dd){    if (!x) return ;   // cout<
<<" "<
<<" "<
<<" "<
<<" "<
<
=t[t[x].r].val) { if (d1 && t[t[x].l].val>tmp) query(t[x].l,caonima,(dd+1)%4); if (d2 && t[t[x].r].val>tmp) query(t[x].r,caonima,(dd+1)%4); } else { if (d2 && t[t[x].r].val>tmp) query(t[x].r,caonima,(dd+1)%4); if (d1 && t[t[x].l].val>tmp) query(t[x].l,caonima,(dd+1)%4); }}

下面是这个题的重点

就是因为\(lis\),所以我们要修改当前点的\(val\)以及他子树内的\(val\),为了下一个点的统计。

这里我们修改的方式是找到这个点对应的kdtree上的节点,然后不停的暴力向上跳。

我们首先把这个对应节点的\(val\)弄成这次我们\(query\)的答案+1,然后依次修改祖先们的子树\(max\)

void upp(int x){    //t[x].val=max(t[x].val,t[x].cao);    t[x].val=max(t[x].cao,max(t[t[x].l].val,t[t[x].r].val));}void update(int x,int pp){    t[x].cao=pp;    upp(x);    x=t[x].fa;    while (x)    {     //cout<<"****"<
<<" "<
<<" "<
<<" "<
<

那么其实这个题就应该差不多了

不得不说细节真的是很多的qwq

具体还是看代码吧

kdtree真神奇!

// luogu-judger-enable-o2// luogu-judger-enable-o2#include
#include
#include
#include
#include
#include
#include
#include
#define mk makr_pair#define ll long longusing namespace std;inline int read(){ int x=0,f=1;char ch=getchar(); while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();} while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} return x*f;}const int maxn = 2e5+1e2;struct KD{ int mn[4]; int val; int l,r,fa; int d[4]; int num; int cao;}; KD t[maxn],now;int a[maxn];int n,m,root,ans,tmp,mval;int back[maxn];int ymh;bool operator<(KD a,KD b){ return a.d[ymh]
> 1; dd++; if (dd==4) dd=0; x = mid; nth_element(t+l,t+x,t+r+1); t[x].fa=fa; t[x].cao=0; for (int i=0;i<=3;i++) t[x].mn[i]=t[x].d[i]; back[t[x].num]=x; if (l
b.d[i]) return 0; return 1;}int calc(int x,KD b){ if (!x) return 0; for (int i=0;i<=3;i++) if (t[x].mn[i]>b.d[i]) return 0; return 1;}void query(int x,KD caonima,int dd){ if (!x) return ; // cout<
<<" "<
<<" "<
<<" "<
<<" "<
<
=t[t[x].r].val) { if (d1 && t[t[x].l].val>tmp) query(t[x].l,caonima,(dd+1)%4); if (d2 && t[t[x].r].val>tmp) query(t[x].r,caonima,(dd+1)%4); } else { if (d2 && t[t[x].r].val>tmp) query(t[x].r,caonima,(dd+1)%4); if (d1 && t[t[x].l].val>tmp) query(t[x].l,caonima,(dd+1)%4); }}void upp(int x){ //t[x].val=max(t[x].val,t[x].cao); t[x].val=max(t[x].cao,max(t[t[x].l].val,t[t[x].r].val));}void update(int x,int pp){ t[x].cao=pp; upp(x); x=t[x].fa; while (x) { //cout<<"****"<
<<" "<
<<" "<
<<" "<
<

转载于:https://www.cnblogs.com/yimmortal/p/10161959.html

你可能感兴趣的文章
MyEclipse DB Browser使用图文全攻略
查看>>
poj3320 Jessica's Reading Problem(尺取思路+STL)
查看>>
A - Vasya and Socks
查看>>
项目管理、设计开发、代码管理、bug管理工具介绍
查看>>
分布式计算开源框架Hadoop介绍
查看>>
安卓平台接口剖析
查看>>
linux文件编码查看与修改
查看>>
[Java] 系统环境变量配置
查看>>
坏的事情不都会带来坏的结果
查看>>
RPC的基础:调研EOS插件http_plugin
查看>>
HIT1946 希尔伯特分形曲线(dfs)
查看>>
第二次团队冲刺第二天
查看>>
青瓷引擎之纯JavaScript打造HTML5游戏第二弹——《跳跃的方块》Part 2
查看>>
bzoj 2257 (JSOI 2009) 瓶子与燃料
查看>>
11)Java abstract class 和 interface
查看>>
使用xrdp或Xmanager 远程连接 CentOS6
查看>>
SEH简单研究
查看>>
Linux误删恢复
查看>>
Unity调用Windows窗口句柄,选择文件和目录
查看>>
HashMap循环遍历方式
查看>>