两题都是朴素想法枚举两个端点O(n^2)超时,那么枚举其中一个端点用线段树维护另一个端点。关键在于没插入一个端点后都是成段更新,否则又会退化到O(N^2)。
ps:两题用c++交都比g++快500ms以上。
4630
//#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
const int maxn=50005;
int tree[maxn<<2],lz[maxn<<2];
void pushdown(int rt)
{
tree[rt]=max(tree[rt],lz[rt]);
lz[rt<<1]=max(lz[rt<<1],lz[rt]);
lz[rt<<1|1]=max(lz[rt<<1|1],lz[rt]);
lz[rt]=-1;
}
void update(int L,int R,int val,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
lz[rt]=max(lz[rt],val);
return ;
}
int mid=(l+r)>>1;
if(R<=mid)
{
pushdown(rt);
update(L,R,val,lson);
tree[rt]=max(tree[rt<<1],lz[rt<<1]);
tree[rt]=max(tree[rt],max(tree[rt<<1|1],lz[rt<<1|1]));
return ;
}
if(L>mid)
{
pushdown(rt);
update(L,R,val,rson);
tree[rt]=max(tree[rt<<1],lz[rt<<1]);
tree[rt]=max(tree[rt],max(tree[rt<<1|1],lz[rt<<1|1]));
return ;
}
pushdown(rt);
update(L,R,val,lson);
update(L,R,val,rson);
tree[rt]=max(tree[rt<<1],lz[rt<<1]);
tree[rt]=max(tree[rt],max(tree[rt<<1|1],lz[rt<<1|1]));
}
int query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
return max(tree[rt],lz[rt]);
}
int mid=(l+r)>>1;
pushdown(rt);
if(R<=mid)
{
return query(L,R,lson);
}
if(L>mid)
{
return query(L,R,rson);
}
return max(query(L,R,lson),query(L,R,rson));
}
int a[maxn];
struct qyy
{
int l,r,id;
qyy(){}
qyy(int a,int b,int c)
{
l=a;r=b;id=c;
}
bool operator< (const qyy &a) const
{
return r<a.r;
}
}qy[maxn];
int qcnt;
struct opt
{
int ans,id;
opt(){}
opt(int a,int b)
{
ans=a;id=b;
}
bool operator< (const opt &a) const
{
return id<a.id;
}
}opt[maxn];
int ocnt;
int pre[maxn];
int main()
{
int t,n,m,i,j,l,r,cnt;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=1;i<=n;++i)
{
scanf("%d",&a[i]);
}
scanf("%d",&m);
qcnt=0;ocnt=0;
for(i=1;i<=m;++i)
{
scanf("%d%d",&l,&r);
if(l==r)
{
opt[ocnt].ans=0;
opt[ocnt++].id=i;
}
else
{
qy[qcnt].id=i;
qy[qcnt].l=l;
qy[qcnt++].r=r;
}
}
sort(qy,qy+qcnt);
memset(pre,-1,sizeof(pre));
memset(tree,-1,sizeof(tree));
memset(lz,-1,sizeof(lz));
cnt=0;
for(i=1;i<=n;++i)
{
for(j=1;j*j<=a[i];++j)
{
if(a[i]%j!=0)
continue;
if(pre[j]!=-1)
{
update(1,pre[j],j,1,n,1);
}
if(pre[a[i]/j]!=-1)
{
update(1,pre[a[i]/j],a[i]/j,1,n,1);
}
pre[j]=i;
pre[a[i]/j]=i;
}
while(cnt<qcnt&&qy[cnt].r==i)
{
opt[ocnt].id=qy[cnt].id;
opt[ocnt++].ans=query(qy[cnt].l,qy[cnt].l,1,n,1);
cnt++;
}
if(cnt==qcnt)
break;
}
sort(opt,opt+m);
for(i=0;i<m;++i)
{
printf("%d\n",opt[i].ans);
}
}
return 0;
}
4638
//#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
const int maxn=100005;
int tree[maxn<<2],lz[maxn<<2];
void pushdown(int rt)
{
lz[rt<<1]+=lz[rt];
lz[rt<<1|1]+=lz[rt];
lz[rt]=0;
}
void update(int L,int R,int val,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
lz[rt]+=val;
return ;
}
pushdown(rt);
int mid=(l+r)>>1;
if(R<=mid)
{
update(L,R,val,lson);
return ;
}
if(L>mid)
{
update(L,R,val,rson);
return ;
}
update(L,R,val,lson);
update(L,R,val,rson);
}
int query(int pos,int l,int r,int rt)
{
if(l==r)
{
return tree[rt]+lz[rt];
}
int mid=(l+r)>>1;
pushdown(rt);
if(pos<=mid)
return query(pos,lson);
else
return query(pos,rson);
}
bool hash[maxn];
int a[maxn];
struct qyy
{
int l,r,id;
qyy(){}
qyy(int a,int b,int c)
{
l=a;r=b;id=c;
}
bool operator< (const qyy& a) const
{
return r<a.r;
}
}qy[maxn];
struct optt
{
int ans,id;
optt(){}
optt(int a,int b)
{
ans=a;id=b;
}
bool operator< (const optt& a) const
{
return id<a.id;
}
}opt[maxn];
int pos[maxn];
int main()
{
int t,n,m,i,j,l,r,cnt,tmp,tmp2,val,ccnt,ocnt;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(i=1;i<=n;++i)
{
scanf("%d",&a[i]);
pos[a[i]]=i;
}
cnt=0;
for(i=1;i<=m;++i)
{
scanf("%d%d",&l,&r);
qy[cnt].id=i;qy[cnt].l=l;qy[cnt].r=r;cnt++;
}
sort(qy,qy+cnt);
memset(hash,false,sizeof(hash));
memset(tree,0,sizeof(tree));memset(lz,0,sizeof(lz));
ccnt=0,ocnt=0;
for(r=1;r<=n;++r)
{
val=a[r];
if(!hash[val-1]&&!hash[val+1])
{
update(1,r,1,1,n,1);
}
else if(hash[val-1]&&!hash[val+1])
{
tmp=pos[val-1];
update(tmp+1,r,1,1,n,1);
}
else if(!hash[val-1]&&hash[val+1])
{
tmp=pos[val+1];
update(tmp+1,r,1,1,n,1);
}
else if(hash[val-1]&&hash[val+1])
{
tmp=min(pos[val-1],pos[val+1]);
tmp2=max(pos[val-1],pos[val+1]);
update(1,tmp,-1,1,n,1);
update(tmp2+1,r,1,1,n,1);
}
hash[val]=true;
while(ccnt<cnt&&qy[ccnt].r==r)
{
opt[ocnt].ans=query(qy[ccnt].l,1,n,1);
opt[ocnt].id=qy[ccnt].id;
ocnt++;ccnt++;
}
if(ccnt==cnt)
break;
}
sort(opt,opt+ocnt);
for(i=0;i<ocnt;++i)
{
printf("%d\n",opt[i].ans);
}
}
return 0;
}