A. Escape from Stones
B. Good Sequences
C. Choosing Balls
D. Colorful Stones:
s串的每个字符对应T串中一个匹配的区间,但是要注意
XXXc1c2
xxxxc2c1
这种状态不可达到 , 所以要剪掉,参考rnq_58的代码
官方题解(很详细了)
线段树优化DP
某个时刻在某个位置会种下一棵树,过一个时刻,树就会长高1单位
还有某个时刻也可能会砍掉某个位置的树,更多条件看题去。
每个操作后求出树的高度的最长递增子序列的长度,
先把每个时刻树都要长高这个条件处理掉,即一开始就给每棵树一棵高度(其实我们并不关心某个树具体多高,只关心相对高度)。
然后注意到每棵树的高度都是不同的,所以可以弄两颗线段树,一棵记录X信息,另一颗记录Y信息
每次插入删除的时候只需要暴力即可,因为x <= 10 (2操作) h<=10(1操作)
#include <cstdio>
#include <cstring>
#include <set>
#include <string>
#include <iostream>
#include <cmath>
#include <vector>
#include <map>
#include <stack>
#include <time.h>
#include <queue>
#include <cstdlib>
#include <algorithm>
using namespace std;
#define lowbit(x) ((x)&(-(x)))
#define sqr(x) ((x)*(x))
#define PB push_back
#define MP make_pair
#define Tr(it, x) for(typeof(x.begin()) it = x.begin(); it!=x.end();it++)
typedef unsigned long long ULL;
typedef long long lld;
typedef vector<int> VI;
typedef vector<string> VS;
typedef pair<int,int> PII;
#define SZ(x) x.size()
#define SORT(x) sort(s.begin(),s.end())
#define REP(i,n) for(int i=0;i<n;i++)
#define For(i,a,b) for(int i=a;i<b;i++)
#define CL(x) memset(x, 0, sizeof(x))
#define CLX(x, y) memset(x, y, sizeof(x))
template <class T> T two(T x) {return 1<<x ;}
template <class T> inline void Min(T &x, T y){if(y < x) x = y;}
template <class T> inline void Max(T &x,T y){if(y > x) x = y;}
const int maxn = 200010;
const int mod = 1000000007;
const int inf = ~0u>>2;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int N = (1<<18 );
struct segtree{
int dp[1<<19];
void update(int p,int val,int l,int r,int rt)
{
if(l == r) {
dp[rt] = val;
return ;
}
int m = l + r >> 1;
if(p <= m) update(p,val,lson);
if(p > m) update(p,val,rson);
dp[rt] = max(dp[rt<<1],dp[rt<<1|1]);
}
int query(int L,int R,int l,int r,int rt)
{
if(L <= l && r <= R) {
return dp[rt];
}
int m = l + r >> 1;
int ans = 0;
if(L <= m) ans = max(ans,query(L,R,lson));
if(R > m) ans = max(ans,query(L,R,rson));
return ans;
}
int query(int p)
{
return query(p,N,1,N,1);
}
void update(int p,int val)
{
update(p,val,1,N,1);
}
};//题目保证不会有两个点的x 或者 y值相等
segtree sgx , sgy;
int n , m;
int toy[maxn+50] , tox[maxn+50];
stack<int> st;
set<int> Q;
void plant(int x,int h)
{
toy[x] = h;
tox[h] = x; Q.insert(x);
for(int i = h - 10;i <= h; i++) {
if(tox[i]){
x = tox[i];
sgx.update(x,0);
sgy.update(i,0);
st.push(i);
}
}
while(!st.empty()){
h = st.top(); st.pop();
x = tox[h];
int mx = sgx.query(x + 1) + 1;
sgx.update(x,mx);
sgy.update(h,mx);
}
}
void cut(int p)
{
int x , h;
while(p){
x = *Q.begin(),Q.erase(Q.begin());
if(toy[x]) {
p--;
st.push(x);
sgx.update(x,0);
sgy.update(toy[x],0);
}
}
x = st.top(); st.pop();
h = toy[x]; tox[h] = toy[x] = 0;
while(!st.empty()) {
x = st.top(); st.pop();
h = toy[x];
int mx = sgy.query(h + 1) + 1;
sgx.update(x,mx);
sgy.update(h,mx);
Q.insert(x);
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
int op , p , h;
cin >> n >> m;
REP(i,m){
scanf("%d",&op);
if(op == 1) {
scanf("%d%d",&p,&h);
plant(p,h + maxn - i);
} else {
scanf("%d",&p);
cut(p);
}
printf("%d\n",sgx.query(1));
}
return 0;
}