1523. K-inversions

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

Consider a permutation a1, a2, …, an (all ai are different integers in range from 1 to n). Let us call k-inversion a sequence of numbers i1, i2, …, ik such that 1 ≤ i1 < i2 < … < ik ≤ n and ai1 > ai2 > … > 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 109.

Samples

inputoutput
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; }

posted on 2012-10-08 17:52  江财小子  阅读(304)  评论(0编辑  收藏  举报