链接在这里呀在这里

其实第一次看到这个题是六月1号。然而即使学长讲了一遍没懂依旧没问敲打 好歹今天一下午终于明白了

一串数字要怎么联想到线段树呢?把数字本身当作线段树中的位置--这个是这题的一个点

Tip2:由于操作只有把开头的一个元素放到最后位置,故,其他数字相对位置不变啊。每次更新的数字就是从开始累加的==

Tip3:n-1-2*a[i]咋来的?对于某个数a[i] 比他大的数有n-1-a[i]个 他位置放到后面 对于别的数而言 又少了a[i]

#include <iostream>
#include<cstdio>
using namespace std;
struct node
{
    int l,r,sum;
}tree[150000];
void build(int root,int l,int r)
{
    tree[root].l=l,tree[root].r=r;
    if(tree[root].l==tree[root].r)
    {
        tree[root].sum=0;
        return;
    }
    build(root<<1,l,(l+r)/2);
    build(root<<1|1,(l+r)/2+1,r);
    tree[root].sum=0;
}
void update(int root,int pos,int val)
{
    if(tree[root].l==tree[root].r)
    {
        tree[root].sum=val;
        return;
    }
    int mid=(tree[root].l+tree[root].r)/2;
    if(pos<=mid) update(root<<1,pos,val);
    else update(root<<1|1,pos,val);///这里写成了build 你脑子在想什么==
    tree[root].sum=min(tree[root<<1].sum,tree[root<<1|1].sum);
}
int main()
{
    //freopen("cin.txt","r",stdin);
    int n,a[12],ret;///
    while(~scanf("%d",&n))
    {
        build(1,1,n);
        ret=0;
        for(int i=0;i<n;i++) {
            scanf("%d",&a[i]);
            ret+=(n-1-2*a[i]);
            update(1,a[i],ret);
        }
        ret=0;
        for(int i=0;i<n-1;i++)
        {
            for(int j=i+1;j<n;j++)
            {
                if(a[i]>a[j]) ret++;
            }
        }
        printf("%d\n",ret+tree[1].sum);
    }
    return 0;
}