BZOJ 4553 [Tjoi2016&Heoi2016]序列
2017-04-02 00:31
375 查看
分治+线段树
记l[i]表示i可能变成的最小值(包括a[i]),同理r[i]最大值。显然i能从j转移当且仅当 i < j ,a[i]<=l[j],r[i]<=a[j],三维偏序,果断分治啊。每一次分治,同样枚举一维,排序一维,剩下一维用线段树即可。
记l[i]表示i可能变成的最小值(包括a[i]),同理r[i]最大值。显然i能从j转移当且仅当 i < j ,a[i]<=l[j],r[i]<=a[j],三维偏序,果断分治啊。每一次分治,同样枚举一维,排序一维,剩下一维用线段树即可。
#include<cstdio> #include<algorithm> #define cmin(u,v) ((u)>(v)?(u)=(v):0) #define cmax(u,v) ((u)<(v)?(u)=(v):0) #define N 100005 using namespace std; namespace runzhe2000 { int a , l , r , arr[N<<1], f , n, m; struct event { int x, y, type, v; bool operator < (const event &that) const {return x == that.x ? type < that.type : x < that.x;} }eve ; struct seg{int v;} t[N*5]; void build(int x, int l, int r) { t[x].v = 0; if(l == r)return; int mid = (l+r)>>1; build(x<<1,l,mid); build(x<<1|1,mid+1,r); } int query(int x, int l, int r, int ql, int qr) { if(ql <= l && r <= qr) return t[x].v; int mid = (l+r)>>1, ret = 0; if(ql <= mid) ret = max(ret, query(x<<1,l,mid,ql,qr)); if(mid < qr) ret = max(ret, query(x<<1|1,mid+1,r,ql,qr)); return ret; } void modi(int x, int l, int r, int p, int v) { if(l == r) {cmax(t[x].v, v); return;} int mid = (l+r)>>1; p <= mid ? modi(x<<1,l,mid,p,v) : modi(x<<1|1,mid+1,r,p,v); t[x].v = max(t[x<<1].v, t[x<<1|1].v); } void dc(int L, int R) { if(L == R) {cmax(f[L], 1); return;} int mid = (L+R)>>1, evecnt = 0, arrcnt = 0; dc(mid+1, R); for(int i = L; i <= mid; i++) arr[++arrcnt] = a[i], arr[++arrcnt] = r[i]; for(int i = mid+1; i <= R; i++) arr[++arrcnt] = l[i], arr[++arrcnt] = a[i]; sort(arr+1, arr+1+arrcnt); arrcnt = unique(arr+1, arr+1+arrcnt) - arr - 1; #define low(u) (int)(lower_bound(arr+1, arr+1+arrcnt, u) - arr) for(int i = L; i <= mid; i++) eve[++evecnt] = (event){low(a[i]), low(r[i]), 0, i}; for(int i = mid+1; i <= R; i++) eve[++evecnt] = (event){low(l[i]), low(a[i]), 1, f[i]}; sort(eve+1, eve+1+evecnt); build(1,1,arrcnt); for(int i = evecnt; i; i--) { if(eve[i].type) modi(1,1,arrcnt, eve[i].y, eve[i].v); else f[eve[i].v] = max(f[eve[i].v], 1 + query(1,1,arrcnt, eve[i].y, arrcnt)); } dc(L,mid); } void main() { scanf("%d%d",&n,&m); for(int i = 1; i <= n; i++) { scanf("%d",&a[i]); l[i] = r[i] = a[i]; } for(int i = 1; i <= m; i++) { int x, y; scanf("%d%d",&x,&y); cmin(l[x], y), cmax(r[x], y); } dc(1,n); int ans = 1; for(int i = 1; i <= n; i++) cmax(ans, f[i]); printf("%d\n",ans); } } int main() { runzhe2000::main(); }
相关文章推荐
- bzoj 4553: [Tjoi2016&Heoi2016]序列 cdq分治+树状数组
- BZOJ 4553 [Tjoi2016&Heoi2016]序列 线段树套treap
- 【BZOJ4553】[Tjoi2016&Heoi2016]序列 cdq分治+树状数组
- [Tjoi2016&Heoi2016]【BZOJ 4553】【JZOJ 4606】序列
- 【bzoj4553】[Tjoi2016&Heoi2016]序列
- Bzoj4553: [Tjoi2016&Heoi2016]序列
- BZOJ 4553: [Tjoi2016&Heoi2016]序列
- [BZOJ4553][TJOI2016&HEOI2016]序列
- Bzoj4553: [Tjoi2016&Heoi2016]序列
- [BZOJ4553][Tjoi2016&Heoi2016]序列 cdp分治+dp
- 【bzoj4553】【TJOI2016&HEOI2016】【序列】【cdq分治+树状数组】
- 【bzoj4553】[Tjoi2016&Heoi2016]序列【树套树 树状数组套平衡树】
- bzoj 4553: [Tjoi2016&Heoi2016]序列 (CDQ分治+DP+树状数组)
- [DP][CDQ分治] BZOJ 4553: [Tjoi2016&Heoi2016]序列
- BZOJ 4553 [Tjoi2016&Heoi2016]序列 ——CDQ分治 树状数组
- bzoj 4553: [Tjoi2016&Heoi2016]序列
- bzoj 4553: [Tjoi2016&Heoi2016]序列
- [bzoj4553][Tjoi2016&Heoi2016]序列 cdq分治
- BZOJ 4553: [Tjoi2016&Heoi2016]序列
- BZOJ 4553: [Tjoi2016&Heoi2016]序列