codeforces 162 div 1(完全)

A. Escape from Stones

B. Good Sequences 

C. Choosing Balls

D. Colorful Stones:

s串的每个字符对应T串中一个匹配的区间,但是要注意

XXXc1c2  

xxxxc2c1

这种状态不可达到 , 所以要剪掉,参考rnq_58的代码

E. Roadside Trees

官方题解(很详细了)

线段树优化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;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值