Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- const long long mod = 1e9+7;
- const double eps = 1e-15;
- double PI = 3.14159265359;
- #define readFile freopen("input","r",stdin)
- #define writeFile freopen("output","w",stdout)
- #define fastIO ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
- typedef pair<long long,long long> ii;
- typedef unsigned long long ULL;
- const long long INF = 1e8;
- const int N =800001,N1 = 400001;
- int _len,_ways;
- #define pnode Node*
- ii mx(ii a,ii b){
- if (a.first>b.first) return a;
- if (a.first<b.first) return b;
- return make_pair(a.first,b.second+a.second);
- }
- struct seg{
- ii ls[N*2];
- seg(){
- for(int i=0;i<N*2;i++) ls[i]=make_pair(0,0);
- }
- ii ls_query(int node,int l,int r,int ll,int rr){
- if(l>rr || r<ll || r<l || rr<ll) return make_pair(0,0);
- if (l>=ll && r<=rr) return ls[node];
- int mid = (l+r)>>1;
- ii q1 = ls_query(node<<1,l,mid,ll,rr);
- ii q2 = ls_query(node<<1|1,mid+1,r,ll,rr);
- return mx(q1,q2);
- }
- ii lds_query(int node,int l,int r,int ll,int rr){
- if(l>rr || r<ll || r<l || rr<ll) return make_pair(0,0);
- if (l>=ll && r<=rr) return ls[node];
- int mid = (l+r)>>1;
- ii q1 = lds_query(node<<1,l,mid,ll,rr);
- ii q2 = lds_query(node<<1|1,mid+1,r,ll,rr);
- return mx(q1,q2);
- }
- ii ls_ins(int node,int l,int r,int idx,ii val){
- if (l==r){
- if (val.first == ls[node].first-1) ls[node].second+=val.second;
- else if (ls[node].first-1<val.first) ls[node] = val,ls[node].first++;
- return ls[node];
- }
- int mid = (l+r)>>1;
- ii res;
- if (idx<=mid) res = ls_ins(node<<1,l,mid,idx,val);
- else res = ls_ins(node<<1|1,mid+1,r,idx,val);
- ls[node] = mx(ls[node<<1],ls[node<<1|1]);
- return res;
- }
- ii lds_ins(int node,int l,int r,int idx,ii val){
- if (l==r){
- if (val.first == ls[node].first-1) ls[node].second+=val.second;
- else if (ls[node].first-1<val.first) ls[node] = val,ls[node].first++;
- return ls[node];
- }
- int mid = (l+r)>>1;
- ii res;
- if (idx<=mid) res = lds_ins(node<<1,l,mid,idx,val);
- else res = lds_ins(node<<1|1,mid+1,r,idx,val);
- ls[node] = mx(ls[node<<1],ls[node<<1|1]);
- return res;
- }
- };
- struct Node{
- int len,ways;
- pnode l,*r;
- Node(){
- l=r=NULL;
- len = ways = 0;
- }
- Node(ii val){
- l =r = NULL;
- this->len = val.first;
- this->ways = val.second;
- }
- Node(pnode l,pnode r){
- this->l = l;
- this->r = r;
- if (l->len > r->len){
- this->len = l->len;
- this->ways = l->ways;
- }
- else if (l->len < r->len){
- this->len = r->len;
- this->ways = r->ways;
- }
- else{
- this->len = r->len;
- this->ways = r->ways+l->ways;
- }
- }
- ii pr(){return make_pair(len,ways);}
- };
- pnode rroots[N1];
- pnode lroots[N1];
- pnode build(int l,int r){
- if (l==r) return new Node();
- int mid = (l+r)>>1;
- return new Node(build(l,mid),build(mid+1,r));
- }
- pnode insert(pnode node,int l,int r,int idx,ii val){
- if (l==r) return new Node(val);
- int mid = (l+r)>>1;
- if (idx<=mid) return new Node(insert(node->l,l,mid,idx,val),node->r);
- return new Node(node->l,insert(node->r,mid+1,r,idx,val));
- }
- ii query(pnode node,int l,int r,int ll,int rr){
- if (l>rr || r<ll) return make_pair(0,0);
- if (l>=ll && r<=rr) return node->pr();
- int mid = (l+r)>>1;
- ii q1 = query(node->l,l,mid,ll,rr);
- ii q2 = query(node->r,mid+1,r,ll,rr);
- return mx(q1,q2);
- }
- ii lef[N/2],ri[N/2];
- int arr[N/2];
- ii q[N/2];
- int n,m,pntr;
- void rc(){
- pair<int,ii> comps[N];
- cin>>n>>m;
- for(int i=1;i<=n;i++){
- cin>>comps[i].first;
- comps[i].second.first = i;
- comps[i].second.second = 0;
- }
- for(int i=1;i<=m;i++){
- int a,b;
- cin>>a>>b;
- comps[n+i].first = b;
- comps[n+i].second = make_pair(i,a);
- }
- sort(comps+1,comps+n+m+1);
- pntr = 0;
- for(int i=1;i<=n+m;i++){
- if (comps[i].first!=comps[i-1].first){
- pntr++;
- }
- if (!comps[i].second.second)
- arr[comps[i].second.first] = pntr;
- else q[comps[i].second.first] = make_pair(comps[i].second.second,pntr);
- }
- }
- int res_query(int a,int x){
- ii q1 = query(rroots[a-1],1,pntr,1,x-1);
- ii q2 = query(lroots[a+1],1,pntr,x+1,pntr);
- int tmp = q1.first+q2.first+1;
- if (tmp>=_len) return tmp;
- if (ri[a].first + lef[a].first -1 <_len) return _len;
- if (ri[a].second*lef[a].second == _ways) return _len-1;
- return _len;
- }
- void process(){
- seg ls = seg();
- for(int i=1;i<=n;i++){
- ii tmp = ls.ls_query(1,1,pntr,1,arr[i]-1);
- if (!tmp.first) tmp = make_pair(0,1);
- ri[i] = ls.ls_ins(1,1,pntr,arr[i],tmp);
- rroots[i] = insert(rroots[i-1],1,pntr,arr[i],ri[i]);
- ri[i].second = tmp.second;
- }
- _len = ls.ls[1].first,_ways = ls.ls[1].second;
- for(int i=0;i<N*2;i++) ls.ls[i] = make_pair(0,0);
- for(int i=n;i>0;i--){
- ii tmp = ls.lds_query(1,1,pntr,arr[i]+1,N);
- if (!tmp.first) tmp = make_pair(0,1);
- lef[i] = ls.lds_ins(1,1,pntr,arr[i],tmp);
- lroots[i] = insert(lroots[i+1],1,pntr,arr[i],lef[i]);
- lef[i].second = tmp.second;
- }
- }
- int main(){
- #ifndef ONLINE_JUDGE
- readFile;
- // writeFile;
- #endif
- fastIO;
- rc();
- rroots[0] = build(1,pntr);
- lroots[n+1] = build(1,pntr);
- process();
- for(int i=1;i<=m;i++){
- cout<<res_query(q[i].first,q[i].second)<<"\n";
- }
- }
Add Comment
Please, Sign In to add comment