1. 程式人生 > >codeforces 650D (樹狀陣列)

codeforces 650D (樹狀陣列)

題意:動態LIS,改變一個值求LIS。

先把詢問離線下來按照改變的位置排序,把所有的數字離散化。首先先用樹狀陣列求出每一位為結尾的最長上升字首f[i]和每一位開始的最長上升字尾g[i],然後考慮每一個數字改變後的LIS情況,分成兩種討論:

  • LIS不包含這個數。這種情況比較簡單,考慮是不是每一個LIS都含有這個數字即可,也即對於所有的LIS,某一位必須是這個數。所以直接統計每一個數字在LIS中的位置,然後判斷這個位置是否唯一即可。

  • LIS包含這個數。對於一個數a[i],顯然需要找到一個j和k使得aj<ai<aki<j<k,直接正反掃兩遍用樹狀陣列統計即可。

#include <cstdio>
#include <iostream> #include <cstring> #include <queue> #include <cmath> #include <algorithm> #include <stack> #include <map> #include <set> #pragma comment(linker, "/STACK:102400000,102400000") #define Clear(x,y) memset (x,y,sizeof(x)) #define Close() ios::sync_with_stdio(0)
#define Open() freopen ("more.in", "r", stdin) #define get_min(a,b) a = min (a, b) #define get_max(a,b) a = max (a, b); #define y0 yzz #define y1 yzzz #define fi first #define se second #define pii pair<int, int> #define pli pair<long long, int> #define pll pair<long long, long long>
#define pb push_back #define pl c<<1 #define pr (c<<1)|1 #define lson tree[c].l,tree[c].mid,pl #define rson tree[c].mid+1,tree[c].r,pr #define mod 1000000007 typedef unsigned long long ull; template <class T> inline T lowbit (T x) {return x&(-x);} template <class T> inline T sqr (T x) {return x*x;} template <class T> inline bool scan (T &ret) { char c; int sgn; if (c = getchar(), c == EOF) return 0; //EOF while (c != '-' && (c < '0' || c > '9') ) c = getchar(); sgn = (c == '-') ? -1 : 1; ret = (c == '-') ? 0 : (c - '0'); while (c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0'); ret *= sgn; return 1; } const double pi = 3.14159265358979323846264338327950288L; using namespace std; #define INF 1e8 #define maxn 800005 #define maxm 1000005 //-----------------morejarphone--------------------// int n, m, cnt; vector <int> num; int a[maxn]; struct Q { int pos, num, id; bool operator < (const Q &a) const { return pos < a.pos; } } qu[maxn]; int f[maxn], g[maxn]; int c[maxn]; void add1 (int x, int num) { for (int i = x; i < maxn; i += lowbit (i)) get_max (c[i], num); } int query1 (int x) { int ans = 0; for (int i = x; i > 0; i -= lowbit (i)) get_max (ans, c[i]); return ans; } void add2 (int x, int num) { for (int i = x; i > 0; i -= lowbit (i)) get_max (c[i], num); } int query2 (int x) { int ans = 0; for (int i = x; i < maxn; i += lowbit (i)) get_max (ans, c[i]); return ans; } int LIS;//LIS的長度 void init () { Clear (c, 0); for (int i = 1; i <= n; i++) { f[i] = query1 (a[i]-1)+1; add1 (a[i], f[i]); } Clear (c, 0); for (int i = n; i >= 1; i--) { g[i] = query2 (a[i]+1)+1; add2 (a[i], g[i]); } LIS = 0; for (int i = 1; i <= n; i++) get_max (LIS, f[i]+g[i]-1); } void lisanhua () { sort (num.begin (), num.end ()); num.erase (unique (num.begin (), num.end ()), num.end ()); cnt = num.size (); for (int i = 1; i <= n; i++) a[i] = lower_bound (num.begin (), num.end (), a[i])-num.begin ()+1; for (int i = 1; i <= m; i++) qu[i].num = lower_bound (num.begin (), num.end (), qu[i].num)-num.begin ()+1; } int ans1[maxn];//不包含每一個數的LIS int tmp[maxn]; void solve1 () { Clear (tmp, 0); for (int i = 1; i <= n; i++) if (f[i]+g[i]-1 == LIS) { tmp[f[i]]++; } for (int i = 1; i <= n; i++) { if (f[i]+g[i]-1 == LIS && tmp[f[i]] == 1) ans1[i] = LIS-1; else ans1[i] = LIS; } } //包含每一個改變值的LIS int ans[maxn];//最後的答案 int l[maxn], r[maxn];//左邊比他小的最長 右邊比他大的最長 void solve2 () { Clear (c, 0); int pos = 1; for (int i = 1; i <= m; i++) { while (pos < qu[i].pos) { add1 (a[pos], f[pos]); pos++; } l[i] = query1 (qu[i].num-1); } Clear (c, 0); pos = n; for (int i = m; i >= 1; i--) { while (pos > qu[i].pos) { add2 (a[pos], g[pos]); pos--; } r[i] = query2 (qu[i].num+1); } for (int i = 1; i <= m; i++) { ans[qu[i].id] = ans1[qu[i].pos]; get_max (ans[qu[i].id], l[i]+r[i]+1); } } int main () { scanf ("%d%d", &n, &m); num.clear (); for (int i = 1; i <= n; i++) { scan (a[i]); num.pb (a[i]); } for (int i = 1; i <= m; i++) { scanf ("%d%d", &qu[i].pos, &qu[i].num); num.pb (qu[i].num); qu[i].id = i; } sort (qu+1, qu+1+m); lisanhua (); init (); solve1 (); solve2 (); for (int i = 1; i <= m; i++) { printf ("%d\n", ans[i]); } return 0; } /* 15 1 76 9 32 82 40 91 46 5 12 69 44 97 30 13 29 2 62 6 3 7 10 6 9 5 8 1 1 6 9 4 11 */