• HDU 5497 Inversion


    Time Limit: 3000MS   Memory Limit: 65536KB   64bit IO Format: %I64d & %I64u

    Description

    You have a sequence {a_1,a_2,...,a_n} and you can delete a contiguous subsequence of length m. So what is the minimum number of inversions after the deletion.
     

    Input

    There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case: 

    The first line contains two integers n, m (1 le n le 10^5, 1 le m < n) - the length of the seuqence. The second line contains n integersa_1,a_2,...,a_n (1 le a_i le n)

    The sum of n in the test cases will not exceed 2 imes 10^6.
     

    Output

    For each test case, output the minimum number of inversions.
     

    Sample Input

    2 3 1 1 2 3 4 2 4 1 3 2
     

    Sample Output

    0 1
     

    Source

    BestCoder Round #58 (div.2)

    滑动区间扫描。用树状数组来维护逆序对的个数(数组存储数n是否已经出现,通过计算数组前缀和来求逆序对,思路和比这篇早些写的POJ2182 Lost Cows类似)

    维护L([i])树状数组表示i左边比a[i]的数的数量,R([i])树状数组表示i右边比a[i]小的数的数量。窗口从左滑到右面,不断更新L和R,计算答案并更新

     1 /*by SilverN*/
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cstdio>
     6 #include<cmath>
     7 using namespace std;
     8 const int mxn=110000;
     9 int n,m;
    10 struct tree{
    11     int a[mxn];
    12     inline lowbit(int x){return x&-x;}
    13     void init(){memset(a,0,sizeof a);}
    14     void add(int x,int num){
    15         while(x<=n){
    16             a[x]+=num;
    17             x+=lowbit(x);    
    18         }
    19         return;
    20     }
    21     int sum(int x){
    22         int res=0;
    23         while(x){
    24             res+=a[x];
    25             x-=lowbit(x);
    26         }
    27         return res;
    28     }
    29 };
    30 int a[mxn];
    31 tree Le,Ri;
    32 int main(){
    33     int T;
    34     scanf("%d",&T);
    35     while(T--){
    36         scanf("%d%d",&n,&m);
    37         int i,j;
    38         for(i=1;i<=n;i++){
    39             scanf("%d",&a[i]);
    40         }
    41         Le.init();
    42         Ri.init();
    43         long long ans;
    44         long long tmp=0;
    45         //求原有逆序对数(最左边滑动窗口内的不算) 
    46         for(i=n;i>m;i--){
    47             Ri.add(a[i],1);
    48             tmp+=Ri.sum(a[i]-1);
    49         }
    50         ans=tmp;
    51         //finish
    52         for(i=1;i<=n-m;i++){
    53             Ri.add(a[i+m],-1);//窗口滑动,窗口最右面的数被删除
    54             tmp=tmp+Ri.sum(a[i]-1)-Ri.sum(a[i+m]-1);
    55             tmp=tmp+Le.sum(n+1-(a[i]+1))-Le.sum(n+1-(a[i+m]+1));
    56             Le.add(n+1-a[i],1);
    57             ans=min(ans,tmp);
    58         }
    59         printf("%lld
    ",ans);
    60     }
    61     return 0;
    62 }
  • 相关阅读:
    【Unity与23种设计模式】命令模式(Command)
    【Unity3D与23种设计模式】组合模式(Composite)
    【Unity3D与23种设计模式】享元模式(Flyweight)
    【Unity3D与23种设计模式】建造者模式(Builder)
    【Unity3D与23种设计模式】工厂方法模式(Factory Method)
    【Unity3D与23种设计模式】模板方法模式(Template Method)
    【Unity3D与23种设计模式】策略模式(Strategy)
    【Unity3D与23种设计模式】桥接模式(Bridge)
    C# 清空数组Array.Clear
    Unity 修改windows窗口的标题
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/5648291.html
Copyright © 2020-2023  润新知