BZOJ4358 : permu
把询问看成二维点,建立kd-tree,每个点维护一个计数器。
从1到n依次加入每个数,每次加入一个数时,对于所有包含它的询问,计数器加一,对于其它询问,计数器置0。
那么每个询问的答案就是计数器的历史最大值,可以通过打标记实现。
时间复杂度。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | #include<cstdio> #include<algorithm> const int N=50010,inf=-1,BUF=2000000; int n,m,i,x,id[N],root,cmp_d,X,a[N]; char Buf[BUF],*buf=Buf; inline void read( int &a){ for (a=0;*buf<48;buf++); while (*buf>47)a=a*10+*buf++-48;} struct node{ int D[2],l,r,Max[2],Min[2]; int m,d,e,hm,hd,he; }t[N]; inline bool cmp( const node&a, const node&b){ return a.D[cmp_d]<b.D[cmp_d];} inline void Max( int &a, int b){ if (a<b)a=b;} inline void Min( int &a, int b){ if (a>b)a=b;} inline void up( int x){ id[t[x].e]=x,t[x].e=t[x].he=inf; if (t[x].l){ Max(t[x].Max[0],t[t[x].l].Max[0]); Min(t[x].Min[0],t[t[x].l].Min[0]); Max(t[x].Max[1],t[t[x].l].Max[1]); Min(t[x].Min[1],t[t[x].l].Min[1]); } if (t[x].r){ Max(t[x].Max[0],t[t[x].r].Max[0]); Min(t[x].Min[0],t[t[x].r].Min[0]); Max(t[x].Max[1],t[t[x].r].Max[1]); Min(t[x].Min[1],t[t[x].r].Min[1]); } } int build( int l, int r, int D){ int mid=(l+r)>>1; cmp_d=D,std::nth_element(t+l+1,t+mid+1,t+r+1,cmp); t[mid].Max[0]=t[mid].Min[0]=t[mid].D[0]; t[mid].Max[1]=t[mid].Min[1]=t[mid].D[1]; if (l!=mid)t[mid].l=build(l,mid-1,!D); if (r!=mid)t[mid].r=build(mid+1,r,!D); return up(mid),mid; } inline void hdoa(node&x, int v){ Max(x.hm,x.m+v); if (x.e>inf)Max(x.he,x.e+v); else Max(x.hd,x.d+v); } inline void hdoc(node&x, int v){Max(x.hm,v);Max(x.he,v);} inline void doa(node&x, int v){ Max(x.hm,x.m+=v); if (x.e>inf)Max(x.he,x.e+=v); else Max(x.hd,x.d+=v); } inline void doc(node&x, int v){Max(x.hm,x.m=v);Max(x.he,x.e=v);x.d=0;} inline void pb(node&x){ if (x.hd){ if (x.l)hdoa(t[x.l],x.hd); if (x.r)hdoa(t[x.r],x.hd);x.hd=0; } if (x.he>inf){ if (x.l)hdoc(t[x.l],x.he); if (x.r)hdoc(t[x.r],x.he); x.he=inf; } if (x.d){ if (x.l)doa(t[x.l],x.d); if (x.r)doa(t[x.r],x.d); x.d=0; } else if (x.e>inf){ if (x.l)doc(t[x.l],x.e); if (x.r)doc(t[x.r],x.e); x.e=inf; } } void change(node&x){ if (x.Min[0]>X||x.Max[1]<X){doc(x,0); return ;} if (x.Max[0]<=X&&x.Min[1]>=X){doa(x,1); return ;} pb(x); if (x.D[0]<=X&&x.D[1]>=X)Max(x.hm,++x.m); else x.m=0; if (x.l)change(t[x.l]); if (x.r)change(t[x.r]); } void dfs(node&x){ pb(x); if (x.l)dfs(t[x.l]); if (x.r)dfs(t[x.r]); } int main(){ fread (Buf,1,BUF,stdin),read(n),read(m); for (i=1;i<=n;i++)read(X),a[X]=i; for (i=1;i<=m;i++)read(t[i].D[0]),read(t[i].D[1]),t[i].e=i; root=build(1,m,1); for (i=1;i<=n;i++)X=a[i],change(t[root]); dfs(t[root]); for (i=1;i<=m;i++) printf ( "%d\n" ,t[id[i]].hm); return 0; } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· DeepSeek智能编程
· 精选4款基于.NET开源、功能强大的通讯调试工具
· [翻译] 为什么 Tracebit 用 C# 开发
· 腾讯ima接入deepseek-r1,借用别人脑子用用成真了~
· DeepSeek崛起:程序员“饭碗”被抢,还是职业进化新起点?