题意:
给出一个序列,求这个序列中满足i!=j&&a[i]%a[j]!=0的个数。
题解:
其实逆问题跟容易求,我们先求a[i]%a[j]==0的个数,然后用总的个数-这个值。总的个数可以用树状数组维护,a[i]%a[j]==0的个数可以枚举每个a[j],然后得到a[j]的倍数从而统计。
#include<iostream> #include<math.h> #include<stdio.h> #include<algorithm> #include<string.h> #include<vector> #include<queue> #include<map> #include<set> #define B(x) (1<<(x)) using namespace std; typedef long long ll; typedef unsigned long long ull; void cmax(int& a,int b){ if(b>a)a=b; } void cmin(int& a,int b){ if(b<a)a=b; } void cmax(ll& a,ll b){ if(b>a)a=b; } void cmin(ll& a,ll b){ if(b<a)a=b; } void add(int& a,int b,int mod){ a=(a+b)%mod; } void add(ll& a,ll b,ll mod){ a=(a+b)%mod; } const int oo=0x3f3f3f3f; const ll OO=0x3f3f3f3f3f3f3f3f; const ll MOD=1000000007; const int maxn = 100005; int a[maxn],num[maxn]; int tree[maxn]; void Init(){ memset(tree,0,sizeof tree); memset(num,0,sizeof num); } int lowbit(int x){ return x&(-x); } void updata(int x){ for(int i=x;i<maxn;i+=lowbit(i)) tree[i]+=1; } int get_sum(int x){ int sum=0; for(int i=x;i>=1;i-=lowbit(i)) sum+=tree[i]; return sum; } int main(){ int n; while(scanf("%d",&n)!=EOF){ Init(); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); num[a[i]]++; updata(a[i]); } ll ans=0; for(int i=1;i<=n;i++){ ll res=0; for(int j=a[i]+a[i];j<=100000;j+=a[i]) res+=num[j]; ans+=(n-get_sum(a[i]))-res; } cout<<ans<<endl; } return 0; }