CodeForces 301D(树状数组)
题目链接:codeforces 301D 题意分析: 解题思路: bool cmp(query a,query b){
return a.x>b.x;
} 2)预处理:找到跟ai的所有可整除的数,根据索引大小保存在1个vector里面: for(int i=1;i<=n;i++)
{
for(int j=a[i];j<=n;j+=a[i])
{
if(p[j]>=i)
vec[i].push_back(p[j]);
else
vec[p[j]].push_back(i);
}
} 3)树状数组处理:有1个虚拟数组cnt int maxx=n+1;
for(int i=0;i<m;i++)
{
int x=q[i].x,y=q[i].y,len;
for(int j=x;j<maxx;j++)
{
len=vec[j].size();
for(int k=0;k<len;k++)
add(vec[j][k],1);
}
ans[q[i].id]=sum(y); //求和
maxx=x;
} AC代码: #include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int n,m,a[200005],p[200005],bit[200005],ans[200005];
vector<int> vec[200005];
struct query{
int id,x,y;
}q[200005];
bool cmp(query a,query b){
return a.x>b.x;
}
int lowbit(int num){
return num&(-num);
}
int sum(int index)
{
int res=0;
for(int i=index;i>0;i-=lowbit(i))
res+=bit[i];
return res;
}
void add(int index,int delta){
for(int i=index;i<=n;i+=lowbit(i))
bit[i]+=delta;
}
int main()
{
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
p[a[i]]=i;
}
for(int i=1;i<=n;i++)
{
for(int j=a[i];j<=n;j+=a[i])
{
if(p[j]>=i)
vec[i].push_back(p[j]);
else
vec[p[j]].push_back(i);
}
}
for(int i=0;i<m;i++)
{
scanf("%d %d",&q[i].x,&q[i].y);
if(q[i].y<q[i].x)
swap(q[i].x,q[i].y);
q[i].id=i;
}
sort(q,q+m,cmp);
int maxx=n+1;
for(int i=0;i<m;i++)
{
int x=q[i].x,len;
for(int j=x;j<maxx;j++)
{
len=vec[j].size();
for(int k=0;k<len;k++)
add(vec[j][k],1);
}
ans[q[i].id]=sum(y);
maxx=x;
}
for(int i=0;i<m;i++)
printf("%d
",ans[i]);
return 0;
} 总结: (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |