mirror of
https://gitcode.com/Zengtudor/alg2025.git
synced 2025-09-05 17:50:36 +00:00
feat: 添加P3660题解实现,使用树状数组计算交叉对数
实现了一个使用树状数组的解法来计算数组中成对元素的交叉对数。通过维护一个访问标记数组和树状数组来高效统计区间和,优化了计算过程。
This commit is contained in:
parent
8aca422b9d
commit
cc3380434c
55
src/9/3/P3660.cpp
Normal file
55
src/9/3/P3660.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <istream>
|
||||
#include <vector>
|
||||
using ll = int64_t;
|
||||
|
||||
ll n,ans=0;
|
||||
std::vector<ll> vis,t,a;
|
||||
|
||||
static inline ll lb(const ll n){
|
||||
return n&(-n);
|
||||
}
|
||||
|
||||
static inline void upd(ll idx,ll add){
|
||||
while(idx<=2*n){ // 注意要*2
|
||||
t[idx]+=add;
|
||||
idx+=lb(idx);
|
||||
}
|
||||
}
|
||||
|
||||
static inline ll get(ll idx){
|
||||
ll res=0;
|
||||
while(idx){
|
||||
res+=t[idx];
|
||||
idx-=lb(idx);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int main(){
|
||||
std::iostream::sync_with_stdio(false);
|
||||
std::cin.tie(nullptr);
|
||||
|
||||
std::cin>>n;
|
||||
a.resize(n*2+1);
|
||||
vis.resize(n+1);
|
||||
t.resize(n*2+1);
|
||||
|
||||
for(ll i=1;i<=n*2;i++){
|
||||
std::cin>>a[i];
|
||||
}
|
||||
|
||||
for(ll i=1;i<=n*2;i++){
|
||||
if(vis[a[i]]){
|
||||
ll nans=get(i)-get(vis[a[i]]);
|
||||
ans+=nans;
|
||||
// printf("%lld += %lld\n",i,nans);
|
||||
upd(vis[a[i]], -1);
|
||||
}else{
|
||||
upd(i, 1);
|
||||
vis[a[i]]=i;
|
||||
}
|
||||
}
|
||||
std::cout<<ans<<"\n";
|
||||
}
|
Loading…
Reference in New Issue
Block a user