#include<iostream>#include<algorithm>#include<cstring>usingnamespace std;constint maxn =100010;typedeflonglong ll;int N, trn, P, a[maxn], tr[maxn];intlowbit(int x){
return x &-x;}voidadd(int id,int c){
for(int i = id; i <= trn; i +=lowbit(i)) tr[i]+= c;}intsum(int id){
int res =0;for(int i = id; i; i -=lowbit(i)){
res += tr[i];}return res;}intmain(){
int T;scanf("%d",&T);while(T--){
scanf("%d",&N);
trn =0;for(int i =1; i <= N; i++){
scanf("%d",&a[i]);
a[i]++;
trn =max(trn, a[i]);}
ll ans =0;for(int i =1; i <= N; i++){
add(a[i],1);
ans += i -sum(a[i]);}scanf("%d",&P);
ll res = ans;memset(tr,0,sizeof tr);while(P--){
int l, r;scanf("%d%d",&l,&r);for(int i = l, k =1; i <= r; i++, k++){
add(a[i],1);
res -= k -sum(a[i]);}//printf("*** %lld\n", res);for(int i = l; i <= r; i++)add(a[i],-1);swap(a[l], a[r]);for(int i = l, k =1; i <= r; i++, k++){
add(a[i],1);
res += k -sum(a[i]);}for(int i = l; i <= r; i++)add(a[i],-1);
ans =min(ans, res);//printf("### %lld\n", res);}printf("%lld\n", ans);}return0;}
C. Curious
题意:计算 ∑ i = 1 n ∑ j = 1 n [ g c d ( a i , a j ) = x ] \sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}[gcd(a_i, a_j) = x] i=1∑nj=1∑n[gcd(ai,aj)=x]
这个题的公式很好推的,我还犹豫那么长时间,觉得不会那么简单…
莫比乌斯反演。我们设 f ( x ) = ∑ i = 1 n ∑ j = 1 n [ g c d ( a i , a j ) = x ] f(x) = \sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}[gcd(a_i, a_j) = x] f(x)=i=1∑nj=1∑n[gcd(ai,aj)=x],则 F ( x ) = ∑ d ∣ n f ( d ) = ∑ i = 1 n ∑ j = 1 n [ x ∣ g c d ( a i , a j ) ] F(x) = \sum\limits_{d|n}f(d) = \sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}[x|gcd(a_i, a_j)] F(x)=d∣n∑f(d)=i=1∑nj=1∑n[x∣gcd(ai,aj)],设 m = ∑ i = 1 n x ∣ a i m = \sum\limits_{i=1}^{n}x|a_i m=i=1∑nx∣ai,则 F ( x ) = m 2 F(x) = m^2 F(x)=m2
因此,令 d ′ = d x , m ′ = ∑ i = 1 n d ′ x ∣ a i d' = \frac{d}{x}, m'=\sum\limits_{i=1}^{n}d'x | a_i d′=xd,m′=i=1∑nd′x∣ai. 则 f ( x ) = ∑ x ∣ d μ ( d x ) m 2 = ∑ d ′ = 1 ∞ μ ( d ′ ) m ′ 2 f(x) = \sum\limits_{x|d}\mu(\frac{d}{x})m^2 = \sum\limits_{d'=1}^{\infty}\mu(d')m'^2 f(x)=x∣d∑μ(xd)m2=d′=1∑∞μ(d′)m′2.