HDU2838 Cow Sorting 樹狀數組 區間求和加逆序數的應用

來源:互聯網
上載者:User

這題目意思很簡單,就是給你一個數組,然後讓你重新排好序,排序有要求的,每次只能交換兩個元素的位置,交換需要一個代價 就是兩個元素之和,問你把數組重小到大排好最少需要多少代價


可能一開始想不到逆序數,我是專門做專題往那邊想才想到的,舉個例子吧
數組: 9 1 0 5 4
此時到 0 的時候,我們先手寫一下最小代價,然後再按照自己的猜測去看看,就是當前掃到0,那麼前面比它大的數有2個,所以先 部分代價為 2 * 0,然後再加上前面比它大的數 也就是9 和1 ,那麼最小代價為10,發現跟手算的一樣,那麼 再多試幾個 最後我們就發現了


對於當前數num,前面有x個比它大的數,那麼走到當前一步的 最小代價為 x*num 再加上前面比它大的數之和


這樣就很容易跟樹狀數組扯上關係了,當前一步的逆序數 其實就是  前面比它大的數的個數,然後同時又能用樹狀數組對於前面比它大的數求和,這樣問題就完美解決了,一開始我看n是10^5次,可能還是沒經驗把,覺得有可能會超,所以就先離散化的做了一遍,可是總是WA,然後離散化去掉以後就過了,不知道為什麼,可是用過掉的代碼跑了很多案例,發現跟離散化版本的 答案是一樣的,真心不知道哪裡寫錯了
離散化的貼出來,希望路過大神 指點:

#include<iostream>#include<cstdio>#include<list>#include<algorithm>#include<cstring>#include<string>#include<stack>#include<map>#include<vector>#include<cmath>#include<memory.h>#include<set>#include<cctype>#define ll long long#define LL __int64#define eps 1e-8//const ll INF=9999999999999;#define inf 0xfffffffusing namespace std;//vector<pair<int,int> > G;//typedef pair<int,int> P;//vector<pair<int,int>> ::iterator iter;////map<ll,int>mp;//map<ll,int>::iterator p;const int N = 500000  + 10;int a[N];int aa[N];int n;typedef struct Node {int v;//原數字int id;//下標};Node p[N];typedef struct C {LL sum;int id;};C c[N];void clear() {    memset(c,0,sizeof(c));memset(aa,0,sizeof(aa));memset(p,0,sizeof(p));}bool cmp(Node x,Node y) {return x.v < y.v;}int lowbit(int x) {    return x&(-x);}//設原始矩陣為a,將a[i]加上val時對c所做的修改void update(int i, int val) {    while (i <= n) {c[i].id += val;        i += lowbit(i);    }} void add(int i,int val) {while(i <= n) {c[i].sum += (1LL) * val;i += lowbit(i);}}int get_sumid(int i) {int sum = 0;while(i > 0) {sum += c[i].id;i -= lowbit(i);}return sum;}//求前i項元素的和int get_sum(int i) {    int sum=0;    while (i > 0) {        sum += c[i].sum;        i -= lowbit(i);    }    return sum;}int main() {    while(scanf("%d",&n) == 1) {clear();//先離散操作for(int i=1;i<=n;i++) {scanf("%d",&p[i].v);a[i] = p[i].v;p[i].id = i;//迴圈序號必須從1開始}sort(p + 1,p + n + 1,cmp);for(int i=1;i<=n;i++)aa[p[i].id] = i;//aa數組存了原來大小資訊LL ans = 0;for(int i=1;i<=n;i++) {update(aa[i],1);add(a[i],a[i]);int ans1 = i - get_sumid(aa[i]);//i代表當前已經插入的個數,ge_sum(aa[i])代表比aa[i]小的數個數,減去即為大的個數,即逆序數if(ans1 != 0) {LL ans2 = (1LL) * get_sum(n) - (1LL) * get_sum(a[i]);ans += (1LL) * ans1 * a[i] + ans2;}}printf("%I64d\n",ans);}    return 0;}

AC代碼:
#include<iostream>#include<cstdio>#include<list>#include<algorithm>#include<cstring>#include<string>#include<stack>#include<map>#include<vector>#include<cmath>#include<memory.h>#include<set>#include<cctype>#define ll long long#define LL __int64#define eps 1e-8//const ll INF=9999999999999;#define inf 0xfffffffusing namespace std;//vector<pair<int,int> > G;//typedef pair<int,int> P;//vector<pair<int,int>> ::iterator iter;////map<ll,int>mp;//map<ll,int>::iterator p;const int N = 500000  + 10;int n;typedef struct C {LL sum;int id;};C c[N];void clear() {    memset(c,0,sizeof(c));}int lowbit(int x) {    return x&(-x);}//設原始矩陣為a,將a[i]加上val時對c所做的修改void update(int i, int val) {int j = i;    while (i <= n) {c[i].id += val;c[i].sum += j;        i += lowbit(i);    }} int get_sumid(int i) {int sum = 0;while(i > 0) {sum += c[i].id;i -= lowbit(i);}return sum;}//求前i項元素的和LL get_sum(int i) {    LL sum=0;    while (i > 0) {        sum += c[i].sum;        i -= lowbit(i);    }    return sum;}int main() {    while(scanf("%d",&n) == 1) {clear();LL ans = 0;for(int i=1;i<=n;i++) {int x;scanf("%d",&x);update(x,1);LL ans1 = i - get_sumid(x);//i代表當前已經插入的個數,ge_sum(aa[i])代表比aa[i]小的數個數,減去即為大的個數,即逆序數if(ans1 != 0) {LL ans2 = get_sum(n) - (1LL) * get_sum(x);ans += ans1 * x + ans2;}}printf("%I64d\n",ans);}    return 0;}/*41 3 2 451 5 3 2 455 4 3 2 17 3 4 5 1 2 7 662 1 6 5 4 374 3 6 5 2 1 7ans:52960465769*/




聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.