• hdu1394线段树点修改,区间求和


    Problem Description
    The inversion number of a given number sequence a1, a2, ..., an is the number of pairs (ai, aj) that satisfy i < j and ai > aj.

    For a given sequence of numbers a1, a2, ..., an, if we move the first m >= 0 numbers to the end of the seqence, we will obtain another sequence. There are totally n such sequences as the following:

    a1, a2, ..., an-1, an (where m = 0 - the initial seqence)
    a2, a3, ..., an, a1 (where m = 1)
    a3, a4, ..., an, a1, a2 (where m = 2)
    ...
    an, a1, a2, ..., an-1 (where m = n-1)

    You are asked to write a program to find the minimum inversion number out of the above sequences.
     
    Input
    The input consists of a number of test cases. Each case consists of two lines: the first line contains a positive integer n (n <= 5000); the next line contains a permutation of the n integers from 0 to n-1.
     
    Output
    For each case, output the minimum inversion number on a single line.
     
    Sample Input
    10 1 3 6 9 0 8 5 7 4 2
     
    Sample Output
    16
     
    一开始看这题时,弄好好久才把题目意思弄懂。
     
     
    题目意思是求最小逆序数,而逆序数就是前面的数大于后面的数,而一串数字又可以移动,现在要求逆序数最小的是有多少。
     
    我们可以先把每个数的当前位置有多少个位置求出来,如a1,a2,a3,a4......an分别对应有b1,b2,b3,b4......bn个逆序数。求出一开始的逆序数sn,但把第一个数放在最后时:
    a2,a3,a4......an,a1  这时的逆序数就sn - a1 + n - a1 - 1 保留最小值即可,然后遍历整个数组就可以求出最小逆序数了。
    下面贴下我写的 线段树+暴力 代码
     
    线段树代码:
     1 #include <iostream>
     2 #include <cstdio>
     3 #define lson l, m, rt<<1
     4 #define rson m+1, r, rt<<1|1
     5 using namespace std;
     6 const int maxn = 5e3+10;
     7 
     8 int min(int a, int b){
     9     return a>b?b:a;
    10 }
    11 int sum[maxn<<2], a[maxn];
    12 void PushUP(int rt){
    13     sum[rt] = sum[rt<<1] + sum[rt<<1|1];
    14 }
    15 void build(int l, int r, int rt){
    16     sum[rt] = 0;
    17     if(l == r)return;
    18     int m = (l + r) >> 1;
    19     build(lson);
    20     build(rson);
    21 }
    22 int query(int L, int R, int l, int r, int rt){
    23     if(L <= l && r <= R){
    24         return sum[rt];
    25     }
    26     int m = (l + r) >> 1;
    27     int ans = 0;
    28     if(m >= L) ans +=query(L, R, lson);
    29     if(m < R) ans += query(L, R, rson);
    30     return ans;
    31 }
    32 void update(int p, int l, int r, int rt){
    33     if(l == r){
    34         sum[rt]++;
    35         return;
    36     }
    37     int m = (l + r) >> 1;
    38     if(p <= m) update(p,lson);
    39     else update(p,rson);
    40     PushUP(rt);
    41 }
    42 int main(){
    43     int n;
    44     while(cin>>n){
    45         int sn = 0;
    46         build(0, n - 1, 1);
    47         for(int i = 0; i < n; i++){
    48             scanf("%d",&a[i]);
    49             sn += query(a[i], n - 1, 0, n -1, 1);
    50             update(a[i], 0, n - 1, 1);
    51         }
    52         int ans = sn;
    53         for(int i = 0; i < n; i++){
    54             sn = sn - a[i] + n - a[i] - 1;
    55             if(sn < ans){
    56                 ans = sn;
    57             }
    58         }
    59         cout << ans << endl;
    60     }
    61     return 0;
    62 }

    暴力代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 using namespace std;
     5 int a[5005],b[5005];
     6 int main(){
     7     int n;
     8     while(cin>>n){
     9         memset(a, 0, sizeof(a));
    10         memset(b, 0, sizeof(b));
    11         for(int i = 0; i < n; i++){
    12             scanf("%d",&a[i]);
    13         }
    14         int sum = 0;
    15         for(int i = 0; i < n; i++){
    16             for(int j = i+1; j < n; j++){
    17                 if(a[i] > a[j]){
    18                     b[i]++;
    19                 }
    20             }
    21             sum += b[i];
    22         }
    23         int minx = sum;
    24         for(int i = 0; i < n; i++){
    25             sum = sum - a[i] + (n - a[i] - 1);
    26             if(sum < minx){
    27                 minx = sum;
    28             }
    29         }
    30         cout << minx << endl;
    31     }
    32     return 0;
    33 }
  • 相关阅读:
    yum管理工具
    ansible简介,简单实用
    ssh服务简介及应用与服务的进程的类型
    keepliave
    NFS
    编译安装redis4.0
    redis多实例和高可用
    NTP时间服务
    ssl简介与openssl的使用
    一些高效学习方法-牛人是怎么来的
  • 原文地址:https://www.cnblogs.com/xingkongyihao/p/6533576.html
Copyright © 2020-2023  润新知