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