LGOJ P4137 Rmq Problem / mex

匿名 (未验证) 提交于 2019-12-03 00:17:01

有一个长度为n的数组\({a_1,a_2,…,a_n}\)\(m\)次询问,每次询问一个区间内最小没有出现过的自然数。

第一行\(n\),\(m\)

第二行为\(n\)个数。

从第三行开始,每行一个询问\(l\),\(r\)

一行一个数,表示每个询问的答案。

输入 #1
5 5
2 1 0 2 1
3 3
2 3
2 4
1 2
3 5
输出 #1
1
2
3
0
3

对于30%的数据:1<=n,m<=1000

对于100%的数据:1<=n,m<=200000,0<=ai<=10^9,1<=l<=r<=n







难点在\(add\)函数上。给我的教训是,变量名最好要有实际意义,不要盲目追求短小,否则巨难debug。

↓拿到了一个新的元素,检查是否是刚刚加入的。如果是,并且这个数是原来区间的\(mex\),那么就暴力更新新的 \(mex\)即可。

inline void add(int pos) {     cnt[a[pos]]++;     if(cnt[a[pos]]==1&&now==a[pos])     {         int tmp=a[pos];         while(cnt[tmp]!=0)tmp++;         now=tmp;         return;     } }





\(o2\)会WA两个点,我猜是\(cmp\)函数的锅:

return (belong[i.l] ^ belong[j.l]) ? (belong[i.l]<belong[j.l]):((belong[i.l]&1)? i.r<j.r:i.r>j.r);

这个玄学优化可能是厌氧的





code:

#include<bits/stdc++.h> using namespace std; const int M=200010; int n,m,a[M],belong[M],size,bnum,ans[M],now; int L=1,R=0,ql,qr; //map<int,int> cnt; int cnt[M];  inline int read() {     char c=getchar();int x=0;     for(;!isdigit(c);c=getchar());     for(;isdigit(c);c=getchar())         x=x*10+c-'0';     return x; }  void pr(int x) {     if(x/10) pr(x/10);     putchar(x%10+'0'); } struct query {     int l,r,id; }q[M];  bool cmp(query i,query j) {     return (belong[i.l] ^ belong[j.l]) ? (belong[i.l]<belong[j.l]):((belong[i.l]&1)? i.r<j.r:i.r>j.r);     //return (belong[i.l]==belong[j.l]) ? i.r<j.r : i.l<j.l; }  inline void add(int pos) {     //if((!(1+cnt[a[x]]))&&a[x]<now)now=a[x];     cnt[a[pos]]++;     if(cnt[a[pos]]==1&&now==a[pos])     { //        cnt[a[x]]++;         int tmp=a[pos];         while(cnt[tmp]!=0)tmp++;         now=tmp;         return;         // while(++tmp)         // {         //     if(cnt[tmp]==0)         //     {         //         now=tmp;         //         return ;         //     }         // }     } }   inline void del(int pos) {     if((!(--cnt[a[pos]]))&&a[pos]<now)now=a[pos]; }  int main() {     n=read();m=read();     for(int i=1;i<=n;i++)a[i]=read();     for(int i=1;i<=m;i++)     {         q[i].id=i;         q[i].l=read();         q[i].r=read();     }     size=sqrt(n);     bnum= ceil((double)n/size);     for(int i=1;i<=bnum;i++)         for(int j=(i-1)*size+1;j<=i*size;j++)             belong[j]=i;    // for(int i=1;i<=n;i++)cout<<belong[i]<<' ';             sort(q+1,q+m+1,cmp);      for(int i=1;i<=m;i++)     {         ql=q[i].l;qr=q[i].r;         while(L<ql) del(L++);         while(L>ql) add(--L);         while(R>qr) del(R--);         while(R<qr) add(++R);         ans[q[i].id]=now;      }     for(int i=1;i<=m;i++)pr(ans[i]),putchar('\n');      return 0; }
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!