I. query
由于是个排列,满足条件的对最多只有n*sqrt(n)个,于是把所有对找出来,由于没有带修操作,所以可以用主席树。
#include
using namespace std;
const int N=1e5+5;
int tot,n,k,f[N],a[N],rt[N];
vectorv[N];
struct node
{
int l,r,sum;
}t[N*200];
int newnode()
{
tot++;t[tot].l=t[tot].r=t[tot].sum=0;return tot;
}
void build(int l,int r,int &now)
{
if(!now) now=newnode();
if(l==r) return;
int m=l+r>>1;
build(l,m,t[now].l);build(m+1,r,t[now].r);
}
void update(int l,int r,int x,int &now,int pre)
{
if(!now) now=newnode(),t[now].sum=t[pre].sum;
t[now].sum++;
if(l==r) return;
int m=l+r>>1;
if(x<=m) update(l,m,x,t[now].l,t[pre].l);
else update(m+1,r,x,t[now].r,t[pre].r);
}
void push(int l,int r,int &now,int pre)
{
if(!now) {now=pre;return;}
if(l==r) return;
int m=l+r>>1;
push(l,m,t[now].l,t[pre].l);
push(m+1,r,t[now].r,t[pre].r);
}
int query(int l,int r,int x,int y,int now,int pre)
{
if(ry) return 0;
if(l>=x&&r<=y) return t[now].sum-t[pre].sum;
int m=l+r>>1;
return query(l,m,x,y,t[now].l,t[pre].l)+query(m+1,r,x,y,t[now].r,t[pre].r);
}
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]),f[a[i]]=i;
for(int i=1;i<=n;i++)
{
for(int j=i+i;j<=n;j+=i)
{
int l=f[i],r=f[j];
if(l>r) swap(l,r);
v[l].push_back(r);
}
}
build(1,n,rt[0]);
for(int i=1;i<=n;i++)
{
for(int j=0;j