HDU 1394
題意 :求 循環(huán)序列的最小逆序數(shù)
線段樹求出最初的逆序數(shù),
吧 Num[1] 移動(dòng)到 最后一位, 逆序數(shù)減少 Num【1】-1,單比Num【1】大的有 n - Num【1】個(gè) ,又會(huì)增加 n - Num【1】個(gè)
故可快速求出 最小逆序數(shù)
#include<iostream> #include<cstdio> #include<cstring> #define lson l, m, rt<<1 #define rson m+1, r, rt << 1|1 using namespace std; const int maxn = 5000 + 31; int Sum[maxn<<2]; int Num[maxn];void PushUp(int rt) {Sum[rt] = Sum[rt<<1] + Sum[rt<<1|1]; }void Build(int l,int r,int rt) {Sum[rt] = 0;if(l == r){return ;}int m = (l + r) >> 1;Build(lson);Build(rson); }void UpDate(int l,int r,int rt,int val) {if(l == val && r == val){Sum[rt] = 1;return ;}int m = (l + r) >> 1;if(val > m) UpDate(rson,val);else UpDate(lson,val);PushUp(rt); }int GetNum(int L,int R,int l,int r,int rt) {if(L <= l && r <= R){return Sum[rt];}int ret = 0;int m = (l + r) >> 1;if(L <= m) ret += GetNum(L,R,lson);if(R > m) ret += GetNum(L,R,rson);return ret; }int main() {int n;while(scanf("%d",&n) != EOF){Build(1,n,1);int sum = 0;int Min = 0;for(int i = 1; i <= n; ++i){scanf("%d",&Num[i]);Num[i]++;sum += GetNum(Num[i],n,1,n,1);UpDate(1,n,1,Num[i]);}//cout << sum <<endl;Min = sum;for(int i = 1; i < n; ++i){sum = sum + (n - 2*Num[i] + 1);Min = min(Min,sum);}printf("%d\n",Min);} }轉(zhuǎn)載于:https://www.cnblogs.com/aoxuets/p/4738947.html
總結(jié)
- 上一篇: 默认开机启动;通过Broadcastre
- 下一篇: hdu 5167 Fibonacci(预