Description
给出一个
1
~
Input
第一行一整数
T
表示用例组数,每组用例首先输入两个证书
Output
对于每次查询,输出查询结果
Sample Input
2
3 1
3 2 1
1 3
6 3
6 5 4 3 2 1
1 6
2 6
3 5
Sample Output
1
8
5
0
Solution
离线,固定右端点R,维护每一个左端点L的答案,对于当前加入的点
P[R]
,找到所有下标小于
R
的
Code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
namespace fastIO
{
#define BUF_SIZE 100000
//fread -> read
bool IOerror=0;
inline char nc()
{
static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE;
if(p1==pend)
{
p1=buf;
pend=buf+fread(buf,1,BUF_SIZE,stdin);
if(pend==p1)
{
IOerror=1;
return -1;
}
}
return *p1++;
}
inline bool blank(char ch)
{
return ch==' '||ch=='\n'||ch=='\r'||ch=='\t';
}
inline void read(int &x)
{
char ch;
while(blank(ch=nc()));
if(IOerror)return;
for(x=ch-'0';(ch=nc())>='0'&&ch<='9';x=x*10+ch-'0');
}
inline void readc(char &x)
{
char ch;
while(blank(ch=nc()));
if(IOerror)return;
x=ch;
}
#undef BUF_SIZE
};
using namespace fastIO;
typedef long long ll;
typedef pair<int,int>P;
const int maxn=100001;
int T,n,m,p[maxn],pos[maxn],num[maxn],temp[maxn];
ll ans[maxn];
vector<P>fact[maxn],q[maxn];
vector<int>pri[maxn];
int mark[maxn];
struct BIT
{
#define lowbit(x) (x&(-x))
ll b[maxn];
void init()
{
memset(b,0,sizeof(b));
}
void add(int x,ll v)
{
while(x<=n)
b[x]+=v,x+=lowbit(x);
}
ll sum(int x)
{
ll ans=0;
while(x)
ans+=b[x],x-=lowbit(x);
return ans;
}
}bit;
void init(int n=100000)
{
for(int i=2;i<=n;i++)
if(!mark[i])
for(int j=i;j<=n;j+=i)
mark[j]=1,pri[j].push_back(i);
for(int i=1;i<=n;i++)
{
int N=1<<pri[i].size();
for(int j=0;j<N;j++)
{
fact[i].push_back(P(1,1));
for(int k=0;k<pri[i].size();k++)
if(j&(1<<k))
fact[i][j].first*=pri[i][k],fact[i][j].second*=-1;
}
}
}
ll Count(int x)
{
ll ans=0;
for(int i=0;i<fact[x].size();i++)
ans+=num[fact[x][i].first]*fact[x][i].second;
return ans;
}
void Deal(int x,int v)
{
for(int i=0;i<fact[x].size();i++)
num[fact[x][i].first]+=v;
}
int main()
{
init();
read(T);
//scanf("%d",&T);
while(T--)
{
bit.init();
//scanf("%d%d",&n,&m);
read(n),read(m);
for(int i=1;i<=n;i++)
{
read(p[i]);
//scanf("%d",&p[i]);
pos[p[i]]=i,q[i].clear();
}
for(int i=1;i<=m;i++)
{
int l,r;
read(l),read(r);
//scanf("%d%d",&l,&r);
q[r].push_back(P(l,i));
}
for(int i=1;i<=n;i++)
{
int res=0;
for(int j=2*p[i];j<=n;j+=p[i])
if(pos[j]<i)temp[++res]=pos[j];
sort(temp+1,temp+res+1);
for(int j=res;j>=1;j--)
{
ll sum=Count(p[temp[j]]/p[i])*p[i];
bit.add(1,sum),bit.add(temp[j]+1,-sum);
Deal(p[temp[j]]/p[i],1);
}
for(int j=1;j<=res;j++)Deal(p[temp[j]]/p[i],-1);
for(int j=0;j<q[i].size();j++)
ans[q[i][j].second]=bit.sum(q[i][j].first);
}
for(int i=1;i<=m;i++)printf("%I64d\n",ans[i]);
}
return 0;
}