1523. K-inversions

http://acm.timus.ru/problem.aspx?space=1&num=1523

Consider a permutation a 1, a 2, …, an (all ai are different integers in range from 1 to n). Let us call k-inversion a sequence of numbers i 1, i 2, …, ik such that 1 ≤  i 1 <  i 2 < … <  ik ≤  n and ai 1 >  ai 2 > … >  aik. Your task is to evaluate the number of different k-inversions in a given permutation.

Input

The first line of the input contains two integers n and k (1 ≤  n ≤ 20000, 2 ≤  k ≤ 10). The second line is filled with n numbers ai.

Output

Output a single number — the number of k-inversions in a given permutation. The number must be taken modulo 10 9.

Samples

input output
3 2

3 1 2

2
5 3

5 4 3 2 1

10

求k-1次逆序数,树状数组的应用
//关键在于理解求逆序数的含义
//其实求一次逆序就是求2个递减数对个数

#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define N 20001 #define M 1000000000 int now,n,k; int a[N],c[N],d[2][N]; int low(int x) { return x&(-x); } void modify(int x,int v) { for(;x<=n;x+=low(x)) c[x]=(c[x]+v)%M; } int query(int x) { int sum=0; for(;x>0;x-=low(x)) sum=(sum+c[x])%M; return sum; } int main() { int temp,sum; while(scanf("%d %d",&n,&k)!=EOF) { now=0; for(int i=1;i<=n;i++) d[1][i]=1,scanf("%d",a+i); for(int i=1;i<k;i++,now^=1) { memset(c,0,sizeof(c)); sum=0; for(int j=i;j<=n;j++) { sum=(sum+d[now^1][j])%M; modify(a[j],d[now^1][j]); temp=query(a[j]); if(sum<=temp) sum+=M; d[now][j]=sum-temp; if(sum>M) sum-=M;//开始这里忘记减回去了、WA了 } } sum=0; for(int i=k;i<=n;i++) sum=(sum+d[now^1][i])%M; printf("%d\n",sum); } return 0; }

你可能感兴趣的:(version)