zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    js 判断中文输入法是否输入完成(系统自带输入法)
    Winform DataGridView中的Button点击事件
    利用sp_addlinkedserver实现远程数据库链接
    锐浪报表多个子报表赋值
    未在本地计算机上注册“Microsoft.ACE.OLEDB.12.0”提供程序
    C# 中解决页面刷新后字体等变大问题
    QRCode 扫描二维码、扫描条形码、相册获取图片后识别、生成带 Logo 二维码、支持微博微信 QQ 二维码扫描样式
    c#4.0 qrcode二维码生成 简单封装
    .net2.0 生成二维码
    c# 生成下部带文字的二维码
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/5648291.html
Copyright © 2011-2022 走看看