链接在这里呀在这里
其实第一次看到这个题是六月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; }