题目链接

\(Description\)

\(Solution\)

还是看代码好理解吧。

为了方便,我们将x坐标左右反转,再将所有高度取反,这样依然是维护从左到右的LIS,但是每次是在右边删除元素。

这样对于在p刚种的树,最多只有9棵树比它高,即它只会转移到这9棵树,除这9棵树外,它可以从1~p-1的任何树转移(其它9棵树除比它高的外 同样可以从它前面任何树转移)。

我们把这9棵树的DP值暴力删掉,然后从低到高 从1~pos[h]-1转移并更新。按高度更新就只需要考虑位置合不合法了。

我们对位置建线段树维护每个位置的DP值,就只有单点修改、区间max。

对于砍掉右数第k棵树,设位置为p,因为只有右边最多9棵树从它转移,同样将它们的DP值暴力删掉,然后删掉位置p的DP值。

但是右边10棵树不一定是最高的,虽然它们可以从前面所有树转移,但还要满足高度小于它们。

这可以二维线段树。但是我们只需要用另一棵线段树对每个高度维护同样的DP值(不同位置高度不同),就可以从左到右,直接用线段树查询并更新了。

这样在一棵线段树上更新完DP值后在另一棵上改一下即可。

复杂度\(O(10n\log n)\)。

总结:是最高的10棵就在维护位置DP值的线段树上转移,是最靠右的10棵就在维护高度DP值的线段树上转移。最后更新一下另一棵的DP值(都维护一样的)。

//840ms	12800KB
#include <set>
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
#define MAXIN 50000
//#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
typedef long long LL;
const int N=2e5+15; int pos[N],h[N];
std::set<int> st;
char IN[MAXIN],*SS=IN,*TT=IN;
struct Segment_Tree
{
#define ls rt<<1
#define rs rt<<1|1
#define lson l,m,ls
#define rson m+1,r,rs
#define S N<<2
int f[N],mx[S];
#undef S #define Update(rt) mx[rt]=std::max(mx[ls],mx[rs])
void Modify(int l,int r,int rt,int p,int v)
{
if(l==r) {mx[rt]=v; return;}
int m=l+r>>1;
if(p<=m) Modify(lson,p,v);
else Modify(rson,p,v);
Update(rt);
}
int Query(int l,int r,int rt,int R)
{
if(r<=R) return mx[rt];
int m=l+r>>1;
if(m<R) return std::max(Query(lson,R),Query(rson,R));
return Query(lson,R);
}
void Insert(int p,int n)//对于新插入的p查询DP值并更新
{
Modify(0,n,1,p,f[p]=Query(0,n,1,p-1)+1);
}
}Tp,Th; 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;
} int main()
{
#define Sp 0,n,1
#define Sh 0,m+10,1
int n=read(),m=read();//pos[i]:高i的树的位置 h[i]:i位置的树的高度
for(int t=1; t<=m; ++t)
if(read()==1)//plant
{
int p=n-read()+1,ht=t+10-read();
pos[ht]=p, h[p]=ht, st.insert(p);
for(int i=ht+1; i<=ht+9; ++i)
if(pos[i]) Tp.Modify(Sp,pos[i],0);
for(int i=ht; i<=ht+9; ++i)
if(pos[i])
{
Tp.Insert(pos[i],n);
Th.f[i]=Tp.f[pos[i]];
Th.Modify(Sh,i,Th.f[i]);
}
printf("%d\n",Tp.mx[1]);
}
else
{
int k=read();
std::set<int>::iterator it=st.end();
while(k--) --it, Th.Modify(Sh,h[*it],0);
Tp.Modify(Sp,*it,0), pos[h[*it]]=0;
for(st.erase(it++); it!=st.end(); ++it)
{
Th.Insert(h[*it],m+10);
Tp.f[*it]=Th.f[h[*it]];
Tp.Modify(Sp,*it,Tp.f[*it]);
}
printf("%d\n",Tp.mx[1]);
} return 0;
}

Codeforces.264E.Roadside Trees(线段树 DP LIS)的更多相关文章

  1. Codeforces.833B.The Bakery(线段树 DP)

    题目链接 \(Description\) 有n个数,将其分为k段,每段的值为这一段的总共数字种类,问最大总值是多少 \(Solution\) DP,用\(f[i][j]\)表示当前在i 分成了j份(第 ...

  2. CodeForces–833B--The Bakery(线段树&&DP)

    B. The Bakery time limit per test 2.5 seconds memory limit per test 256 megabytes input standard inp ...

  3. 线段树解LIS

    先是nlogn的LIS解法 /* LIS nlogn解法 */ #include<iostream> #include<cstring> #include<cstdio& ...

  4. [Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路)

    [Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路) 题面 有n个空心物品,每个物品有外部体积\(out_i\)和内部体积\(in_i\),如果\(in_i& ...

  5. Tsinsen A1219. 采矿(陈许旻) (树链剖分,线段树 + DP)

    [题目链接] http://www.tsinsen.com/A1219 [题意] 给定一棵树,a[u][i]代表u结点分配i人的收益,可以随时改变a[u],查询(u,v)代表在u子树的所有节点,在u- ...

  6. HDU 3016 Man Down (线段树+dp)

    HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Ja ...

  7. Buses and People CodeForces 160E 三维偏序+线段树

    Buses and People CodeForces 160E 三维偏序+线段树 题意 给定 N 个三元组 (a,b,c),现有 M 个询问,每个询问给定一个三元组 (a',b',c'),求满足 a ...

  8. CodeForces 877E DFS序+线段树

    CodeForces 877E DFS序+线段树 题意 就是树上有n个点,然后每个点都有一盏灯,给出初始的状态,1表示亮,0表示不亮,然后有两种操作,第一种是get x,表示你需要输出x的子树和x本身 ...

  9. [Codeforces 1199D]Welfare State(线段树)

    [Codeforces 1199D]Welfare State(线段树) 题面 给出一个长度为n的序列,有q次操作,操作有2种 1.单点修改,把\(a_x\)修改成y 2.区间修改,把序列中值< ...

随机推荐

  1. apache httpd.conf

    Apache的主配置文件:/etc/httpd/conf/httpd.conf 默认站点主目录:/var/www/html/ Apache服务器的配置信息全部存储在主配置文件/etc/httpd/co ...

  2. centos6.5环境利用scp实现自动化文件备份

    centos6.5环境利用scp自动上传备份文件到指定服务器中 需要备份的主机 192.168.3.17 存放备份的主机 192.168.3.18 目的:将3.17主机上/data/storage的文 ...

  3. freeswitch用户整合(使用mysql数据库的用户表)

    转:freeswitch用户整合(使用mysql数据库的用户表) freeswitch是一款强大的voip服务器,可以语音和视频.但是它默认是采用/directory文件夹下的xml来配置用户的,对于 ...

  4. Python-HTML CSS 练习

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  5. sql in语句

    转自http://www.1keydata.com/cn/sql/sql-in.php 在 SQL 中,在两个情况下会用到 IN 这个指令:这一页将介绍其中之一 -- 与 WHERE 有关的那一个情况 ...

  6. LeetCode(48):旋转图像

    Medium! 题目描述: 给定一个 n × n 的二维矩阵表示一个图像. 将图像顺时针旋转 90 度. 说明: 你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵.请不要使用另一个矩阵来旋转 ...

  7. bootstrap----屏幕大小切换

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. poj1015 01二维背包

    /* 给定辩控双方给每个人的打分p[i],d[i], dp[j][k]表示前i个人有j个被选定,选定的人的辩控双方打分差之和是k,此状态下的最大辩控双方和 按01背包做,体积一维是1,体积二维是辩控双 ...

  9. MySQL索引底层实现原理

    优秀博文: MySQL索引背后的数据结构及算法原理 B树.B-树.B+树.B*树[转],mysql索引 MySQL 和 B 树的那些事 索引的本质 MySQL官方对索引的定义为:索引(Index)是帮 ...

  10. 数论知识点总结(noip范围)

    数论知识点: 约数个数和约数和公式(例题:POJ1845 分治思想): 质因数分解 p1^k1xp2^k2xp3^k3...pn^kn 约数个数和:(1+k1)(1+k2)...(1+kn) 所有约数 ...