標籤:std lse \n size style oid 最大的 space 元素
一、題意
給定一個序列,之後給出若干個修改,修改的內容為在原序列的基礎上,將某一位元素的值改成給定的值<每次修改相互獨立,不儲存修改後的結果>。之後詢問,在選擇第一位元素的情況下,最長遞增子序列的長度是多少。
二、題解
考慮不經修改的情況,應當設dp[i]為選取當前位情況下的最長遞增子串的長度。則對於這道題,應當認為對於修改a為b,設l_pos為a左邊最大的元素的位置,r_pos為a右邊大於max(b,r_pos)的元素的位置。則有ans = dp[1] - dp[l_pos] + 1 + dp[r_pos];對於b本身大於位於l_pos的元素,應當給結果+1。
#include<bits/stdc++.h>using namespace std;#define ll long long const int MAXN = 1000233;class Node{ public: int l,r,lc,rc,maxx;};Node nodes[MAXN];int nodes_num;int t,n,m;int arr[MAXN];int dp[MAXN];void tree_init(int a,int b){ int now = nodes_num++; nodes[now].l = a; nodes[now].r = b; if(a == b-1){ nodes[now].maxx = arr[a]; return ; } int mid = (a+b)/2; nodes[now].lc = nodes_num; tree_init(a,mid); nodes[now].rc = nodes_num; tree_init(mid,b); nodes[now].maxx = max(nodes[nodes[now].lc].maxx,nodes[nodes[now].rc].maxx);}int find_max(int now){ int l = nodes[now].l; int r = nodes[now].r; if(l == r-1)return l; int maxx = nodes[now].maxx; int lc = nodes[now].lc; int rc = nodes[now].rc; if(maxx == nodes[lc].maxx)return find_max(lc); else return find_max(rc);}int find_biggest(int now,int a,int b){ int l = nodes[now].l; int r =nodes[now].r; if(l == a&&r == b){ return find_max(now); } int mid = (l+r)/2; int ret ; int lc = nodes[now].lc; int rc = nodes[now].rc; if(a<mid){ ret = find_biggest(lc,a,min(b,mid)); if(b>mid){ int tmp = find_biggest(rc,mid,b); ret = arr[ret] >= arr[tmp] ? ret:tmp; } }else ret = find_biggest(rc,a,b); return ret;}int find_left(int now,int key){ int l = nodes[now].l; int r = nodes[now].r; if(l == r-1)return l; int lc = nodes[now].lc; int rc = nodes[now].rc; if(nodes[lc].maxx > key)return find_left(lc,key); else return find_left(rc,key);}int find_first(int now,int pos, int key){ int l = nodes[now].l; int r = nodes[now].r; if(l >= pos){ return find_left(now,key); } int mid = (l+r)/2; int lc = nodes[now].lc; int rc = nodes[now].rc; int ret ; if(pos < mid && nodes[lc].maxx > key){ ret = find_first(lc,pos,key); if(ret >= pos && arr[ret] > key)return ret; } if(nodes[rc].maxx <= key)return r-1; return find_first(rc,pos,key); }void init(){ scanf("%d %d",&n,&m); nodes_num = 0; arr[0] = -100233; arr[n+1] = INT_MAX; for(int i=1;i<=n;++i)scanf("%d",&arr[i]); tree_init(0,n+2); memset(dp,0,sizeof(dp)); for(int i=n;i>=1;--i){ dp[i] = dp[find_first(0,i+1,arr[i])]+1; } dp[0] = dp[1]+1; for(int i=0;i<m;++i){ int a,b; scanf("%d %d",&a,&b); int l_pos = find_biggest(0,0,a); int key = max(b,arr[l_pos]); int r_pos = find_first(0,a+1,max(b,arr[l_pos])); int ans = dp[1] - dp[l_pos] + 1 + dp[r_pos]; if(b > arr[l_pos] )ans++; cout<<ans<<‘\n‘; }}int main(){ cin>>t; while(t--)init(); return 0;}
HDU暑假多校第八場J-Taotao Picks Apples