全RE求调,线段树,样例能过

P1908 逆序对

only_once @ 2024-07-08 09:58:34

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<cstdio>
#define bug cout<<"-bug-"
#define endl "\n"
#define int long long
#define mem(a,b) memset(a,b,sizeof a)
using namespace std;
const int N=5e5+5;
int n,ans;
struct node{
    int l,r,root,sum;
}tree[4*N];
void update(int root){
    tree[root].sum=tree[root*2+1].sum+tree[root*2].sum;
}
void build(int l,int r,int root){
    tree[root].l=l;
    tree[root].r=r;
    if(l==r) return ;
    int mid=(l+r)>>1;
    build(l,mid,root*2);
    build(mid+1,r,root*2+1);
    update(root);
}
int cheak(int l,int r,int root){
    if(l<=tree[root].l&&r>=tree[root].r) return tree[root].sum;
    int ans=0;
    int mid=(tree[root].l+tree[root].r)>>1;
    if(l<=mid) ans+=cheak(l,r,root*2);
    if(r>mid) ans+=cheak(l,r,root*2+1);
    return ans;
}
void change(int x,int root){
    if(tree[root].l==x&&tree[root].r==x){
        tree[root].sum++;
        return ;
    }
    int mid=(tree[root].l+tree[root].r)>>1;
    if(x<=mid) change(x,root*2);
    else change(x,root*2+1);
    update(root);
}
signed main(){
    cin>>n;
    build(1,n,1);
    for(int i=1;i<=n;i++){
        int x;
        cin>>x;
        if(x!=n) ans+=cheak(x+1,n,1);
        change(x,1);
    }
    cout<<ans;
    return 0;
}

|