codeforces 162 div 1(完全)

来源:互联网 发布:闲鱼上推淘宝客链接 编辑:程序博客网 时间:2024/06/06 23:08

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|1const 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);    #endifint  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;}