Ta nhận thấy rằng, mỗi truy vấn có thể quy về thành hai phép cập nhật gán phần tử. Cụ thể,
đặt A[x]=uA[x]=u và A[y]=vA[y]=v (trước khi hoán đổi), ta chỉ cần xử lý hai phép gán A[x]:=vA[x]:=v và
A[y]:=uA[y]:=u, và bài toán trở nên đơn giản hơn.
Gọi cntcnt là số nghịch đảo trong mảng AA, cntcnt sau khi cập nhật A[i]:=xA[i]:=x thay đổi
như sau:
+ cntcnt trừ đi số lượng jj sao cho j<ij<i và A[j]>A[i]A[j]>A[i];
+ cntcnt tăng một lượng bằng số lượng jj sao cho j<ij<i và A[j]>xA[j]>x;
+ cntcnt trừ đi số jj sao cho j>ij>i và A[i]>A[j]A[i]>A[j];
+ cntcnt tăng một lượng bằng số jj sao cho j>ij>i và x>A[j]x>A[j].
Để thực hiện điều này, ta chia mảng AA thành BB block, mỗi block sẽ có một cây
BIT quản lý tần số xuất hiện các giá trị trong block đó. Khi đó, để tính số lượng jj
thỏa mãn từng điều kiện (với jj không nằm cùng block với ii), ta chỉ cần duyệt qua các
block và thực hiện get trên các cây BIT tương ứng. Ngoài ra, để xét các jj nằm trong cùng
block với ii, ta chỉ cần duyệt qua các phần tử của block đó để tính lại cntcnt.
Cuối cùng, ta cần chọn giá trị BB phù hợp. Để ý rằng độ phức tạp thời gian xử lý mỗi phép
cập nhật là O(2×B×logn+n/B)O(2×B×logn+n/B). Để thời gian được tối ưu, ta chọn BB sao
cho hai hạng tử bằng nhau, và ta tính được ta nên chia AA thành xấp xỉ 5555 block, mỗi
block chứa xấp xỉ 18001800 phần tử.
Code mẫu:
cpp#∈clude<bitsstdc++.h>#def∈elllonglong#def∈edebug(x)cout〈#x〈 = 〈x〈′n′#def∈eall(a)a.beg∈(),a.end()usingnamespacestd;const∫mxn=1e5+3;constllmod=998244353;const∫∈f32=2e9;constll∈f64=7e18;structBIT{∫n,∑;→→r<∫>bit;voit(∫size){n=size,∑=0;bit.resize(n+1);for(∫i=0;i≤n;++i)bit[i]=0;}vopdate(∫i,∫val){for(;i≤n;i+=(i&-i))bit[i]+=val;∑+=val;}∫≥t(∫i){∫res=0;for(;i;i≡(i&-i))res+=bit[i];returnres;}∫≥t(∫l,∫r){if(l==1)return≥t(r);if(r==n)return∑-≥t(l-1);return0;}}bit[501];ll∈v[501];/∈v[id]=sốnghịchđảotrongblocklcnt=0;∫n,q,a[mxn],M;const∫S=2e3;/sốlượngsố>valtrongcácblocktrướcbl∈l∈e∫countgr(∫bl,∫val){∫res=0;for(∫block=0;block<bl;++block){if(block⋅S+S-1>n-1)break;res+=bit[block].≥t(val+1,n);}returnres;}/sốlượngsố<valtrongcácblocksaubl∈l∈e∫countls(∫bl,∫val){∫res=0;for(∫block=bl+1;block<M;++block){if(block⋅S+S-1>n-1)break;res+=bit[block].≥t(1,val-1);}returnres;}vo∮update(∫∫val){∫block=S;cnt≡∈v[block];cnt≡(countgr(block,a[id])+countls(block,a[id]));cnt+=(countgr(block,val)+countls(block,val));∫l=block⋅S,r=min(n-1,l+S-1);for(∫i=l;i<++i)∈v[block]=∈v[block]-(a[i]>a[id])+(a[i]>val);for(∫i=1;i≤r;++i)∈v[block]=∈v[block]-(a[id]>a[i])+(val>a[i]);bit[block].update(a[id],-1);bit[block].update(val,1);a[id]=val;cnt+=∈v[block];}voolve(){c∈〉n〉q;for(∫i=0;i<n;++i)a[i]=i+1;for(∫block=0;block<S;++block){bit[block].∈it(n);∫l=block⋅S,r=min(n-1,l+S-1);if(l>n-1)break;++M;/sốlượngblockfor(∫i=l;i≤r;++i){bit[block].update(a[i],1);}}∫x,y,tmpx,tmpy;whi≤(q--){c∈〉x〉y;--x,--y;tmpx=a[x],tmpy=a[y];p∮update(x,tmpy);p∮update(y,tmpx);cout〈cnt〈′n′;}}∫ma∈(){iosbase::syncwithstdio(false);c∈.tie(NULL);solve();return0;}cpp#∈clude<bitsstdc++.h>#def∈elllonglong#def∈edebug(x)cout⟨#x⟨ = ⟨x⟨'n'#def∈eall(a)a.beg∈(),a.end()usingnamespacestd;const∫mxn=1e5+3;constllmod=998244353;const∫∈f32=2e9;constll∈f64=7e18;structBIT{∫n,∑;→−−→r<∫>bit;voit(∫size){n=size,∑=0;bit.resize(n+1);for(∫i=0;i≤n;++i)bit[i]=0;}vopdate(∫i,∫val){for(;i≤n;i+=(i&−i))bit[i]+=val;∑+=val;}∫≥t(∫i){∫res=0;for(;i;i≡(i&−i))res+=bit[i];returnres;}∫≥t(∫l,∫r){if(l==1)return≥t(r);if(r==n)return∑−≥t(l−1);return0;}}bit[501];ll∈v[501];/∈v[id]=sốnghịchđảotrongblocklcnt=0;∫n,q,a[mxn],M;const∫S=2e3;/sốlượngsố>valtrongcácblocktrướcbl∈l∈e∫countgr(∫bl,∫val){∫res=0;for(∫block=0;block<bl;++block){if(block⋅S+S−1>n−1)break;res+=bit[block].≥t(val+1,n);}returnres;}/sốlượngsố<valtrongcácblocksaubl∈l∈e∫countls(∫bl,∫val){∫res=0;for(∫block=bl+1;block<M;++block){if(block⋅S+S−1>n−1)break;res+=bit[block].≥t(1,val−1);}returnres;}vo∮update(∫∫val){∫block=S;cnt≡∈v[block];cnt≡(countgr(block,a[id])+countls(block,a[id]));cnt+=(countgr(block,val)+countls(block,val));∫l=block⋅S,r=min(n−1,l+S−1);for(∫i=l;i<++i)∈v[block]=∈v[block]−(a[i]>a[id])+(a[i]>val);for(∫i=1;i≤r;++i)∈v[block]=∈v[block]−(a[id]>a[i])+(val>a[i]);bit[block].update(a[id],−1);bit[block].update(val,1);a[id]=val;cnt+=∈v[block];}voolve(){c∈⟩n⟩q;for(∫i=0;i<n;++i)a[i]=i+1;for(∫block=0;block<S;++block){bit[block].∈it(n);∫l=block⋅S,r=min(n−1,l+S−1);if(l>n−1)break;++M;/sốlượngblockfor(∫i=l;i≤r;++i){bit[block].update(a[i],1);}}∫x,y,tmpx,tmpy;whi≤(q−−){c∈⟩x⟩y;−−x,−−y;tmpx=a[x],tmpy=a[y];p∮update(x,tmpy);p∮update(y,tmpx);cout⟨cnt⟨'n';}}∫ma∈(){iosbase::syncwithstdio(false);c∈.tie(NULL);solve();return0;}