BZOJ4358: permu
2015-12-23 18:40
351 查看
Description
给出一个长度为n的排列P(P1,P2,...Pn),以及m个询问。每次询问某个区间[l,r]中,最长的值域连续段长度。
Input
第一行两个整数n,m。接下来一行n个整数,描述P。
接下来m行,每行两个整数l,r,描述一组询问。
Output
对于每组询问,输出一行一个整数,描述答案。Sample Input
8 33 1 7 2 5 8 6 4
1 4
5 8
1 7
Sample Output
33
4
HINT
对于询问[1,4],P2,P4,P1组成最长的值域连续段[1,3];对于询问[5,8],P8,P5,P7组成最长的值域连续段[4,6];
对于询问[1,7],P5,P7,P3,P6组成最长的值域连续段[5,8]。
1<=n,m<=50000
首先O(N^1.5*logN)的莫队套线段树做法应该是谁都会的。
#include<cstdio> #include<cctype> #include<queue> #include<cmath> #include<cstring> #include<algorithm> #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define ren for(int i=first[x];i;i=next[i]) using namespace std; const int BufferSize=1<<16; char buffer[BufferSize],*head,*tail; inline char Getchar() { if(head==tail) { int l=fread(buffer,1,BufferSize,stdin); tail=(head=buffer)+l; } return *head++; } inline int read() { int x=0,f=1;char c=Getchar(); for(;!isdigit(c);c=Getchar()) if(c=='-') f=-1; for(;isdigit(c);c=Getchar()) x=x*10+c-'0'; return x*f; } const int maxn=50010; int n,m,A[maxn],bl[maxn],en[maxn],ans[maxn]; struct Query { int l,r,id; bool operator < (const Query& ths) const { if(bl[l]==bl[ths.l]) return r<ths.r; return l<ths.l; } }Q[maxn]; int findset(int* pa,int x) {return pa[x]==x?x:pa[x]=findset(pa,pa[x]);} int pa[maxn],s[maxn],vis[maxn],nowans; void add(int u) { int v;s[u]=1;pa[u]=u; if(v=findset(pa,u-1)) pa[v]=u,s[u]+=s[v]; if(v=findset(pa,u+1)) pa[v]=u,s[u]+=s[v]; nowans=max(nowans,s[u]); } int pa2[maxn],mx[maxn],mn[maxn],S[maxn],top; void add2(int u,int& res) { int v;pa2[u]=u;mx[u]=mn[u]=u;S[++top]=u; if(v=findset(pa2,u-1)) mn[u]=mn[v]; else if(v=findset(pa,u-1)) mn[u]-=s[v]; if(v=findset(pa2,u+1)) mx[u]=mx[v]; else if(v=findset(pa,u+1)) mx[u]+=s[v]; res=max(res,mx[u]-mn[u]+1); S[++top]=mx[u];pa2[mx[u]]=u; S[++top]=mn[u];pa2[mn[u]]=u; } int main() { n=read();m=read();int SIZE=(int)sqrt(n); rep(i,1,n) A[i]=read(),bl[i]=(i-1)/SIZE+1,en[bl[i]]=i; rep(i,1,m) Q[Q[i].id=i].l=read(),Q[i].r=read(); sort(Q+1,Q+m+1); rep(i,1,m) { int p=i,cur;nowans=0; while(bl[Q[p].l]==bl[Q[i].l]&&p<=m) p++; memset(pa,0,sizeof(pa)); cur=en[bl[Q[i].l]]; rep(j,i,p-1) { while(cur<Q[j].r) add(A[++cur]); ans[Q[j].id]=nowans; rep(k,Q[j].l,min(Q[j].r,en[bl[Q[i].l]])) add2(A[k],ans[Q[j].id]); while(top) pa2[S[top--]]=0; } i=p-1; } rep(i,1,m) printf("%d\n",ans[i]); return 0; }
View Code
相关文章推荐
- HDU 2138:How many prime numbers 【水】
- Android 监听虚拟键盘的展现与隐藏
- hdu 5583 Kingdom of Black and White
- 腾讯分析系统架构解析
- 使用Vmware安装CentOS作为web开发机实践
- hdu 5583 Kingdom of Black and White
- opencv处理透明图片
- 如何让natTable表格支持自定义多个右键菜单
- C++中实现从std::string类型到bool型的转换
- maven引入jar包时,一个jar的引入错误,会导致后来的jar包的引入。
- Spring MVC 配置Controller详解
- 线程的并发与并行
- test
- JavaScript_通过onmouseover onmouseout 部分显示与隐藏
- 面试总结8--计算机网络相关问题Part2
- phpStudy报错
- Ajax的使用
- js获取url参数 兼容某些带#url
- 30多个iOS常用动画,带详细注释(转)
- ViewStub的介绍