The 2018 ACM-ICPC China JiangSu Provincial Programming Contest B Array (滾動陣列+規律)
JSZKC is the captain of the lala team.
There are NN girls in the lala team. And their height is [1,N]and distinct. So it means there are no two girls with a same height.
JSZKC has to arrange them as an array from left to right and let h_ihi be the height of the i^{th}ith girl counting from the left. After that, he can calculate the sum of the inversion pairs. A inversion pair counts if hi>hj with i<j.
Now JSZKC wants to know how many different arranging plans with the sum of the inversion pairs equaling K. Two plans are considered different if and only if there exists an ii with hi different in these two plans.
As the answer may be very large, you should output the answer mod 1000000007.
Input Format
The input file contains several test cases, each of them as described below.
- The first line of the input contains two integers N and K (1≤N≤5000,0≤K≤5000), giving the number of girls and the pairs that JSZKC asked.
There are no more than 5000test cases.
Output Format
An integer in one line for each test case, which is the number of the plans mod 1000000007.
樣例輸入
3 2 3 3
樣例輸出
2 1
找n的全排列中,逆序對的個數是k個的排列個數,網上題解都在說動態規劃,這個題,難道不是打表找一下規律就能看出來的嗎?最關鍵的地方就是滾動陣列了,由於記憶體限制,只能用滾動陣列來做,滾動陣列的話又要將詢問全部輸入後,再按順序進行計算,最後輸出結果。
程式碼實現:
#include<bits/stdc++.h>
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define SI(i) scanf("%d",&i)
#define PI(i) printf("%d\n",i)
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int MAX=1e6+5;
const int INF=0x3f3f3f3f;
const double eps=1e-8;
int dir[9][2]={0,1,0,-1,1,0,-1,0, -1,-1,-1,1,1,-1,1,1};
template<class T>bool gmax(T &a,T b){return a<b?a=b,1:0;}
template<class T>bool gmin(T &a,T b){return a>b?a=b,1:0;}
template<class T>void gmod(T &a,T b){a=((a+b)%mod+mod)%mod;}
ll gcd(ll a,ll b){ while(b) b^=a^=b^=a%=b; return a;}
ll inv(ll b){return b==1?1:(mod-mod/b)*inv(mod%b)%mod;}
struct node{
int x;int y;int index;
}p[5005];
int cnt;
int dp[2][5005];
int ans[5005];
bool cmp1(node a,node b)
{
if(a.x == b.x) return a.y < b.y;
return a.x < b.x;
}
int main()
{
int n,m,i,j,k;
for(i = 0;i <= 1;i++) dp[i][0] = 1;
int flag = 1;
while(~scanf("%d%d",&p[cnt].x,&p[cnt].y))
{
p[cnt].index = cnt++;
}
sort(p,p+cnt,cmp1);
int now = 0;
for(i = 1;i <= 5000;i++)
{
int t = (i-1)*i/2;
for(j = 1;j <= min(t,5000);j++)
{
if(i >= 5 && j >= i)
{
if(j <= t/2) dp[flag][j] = ((ll)dp[flag^1][j]+dp[flag][j-1]-dp[flag^1][j-i]+mod)%mod;
else dp[flag][j] = dp[flag][t-j];
}
else
{
if(j > t/2) dp[flag][j] = dp[flag][t-j];
else dp[flag][j] = ((ll)dp[flag^1][j]+dp[flag][j-1])%mod;
}
}
while(now < cnt && p[now].x == i)
{
//cout<<dp[flag][p[now].y]<<"***"<<p[now].y<<endl;
ans[p[now].index] = dp[flag][p[now].y];
now++;
}
flag ^= 1;
}
for(i = 0;i < cnt;i++)
printf("%d\n",ans[i]);
}