C - K-inversions URAL - 1523 (dp + 線段樹)
阿新 • • 發佈:2018-12-16
題目連結:https://cn.vjudge.net/contest/275079#problem/C
具體思路:我們可以分層的去建立,假設我們要找k層,我們可以先把滿足1.2....k-1層的滿足情況的找出來,然後就可以求出k層的了.這個過程需要線段樹的維護,每一次我們先找出當前這個在滿足情況下的個數,然後不停的往下跟新就可以了.
AC程式碼:
#include<iostream> #include<cstring> #include<iomanip> #include<stdio.h> #include<cmath> using namespace std; # define inf 0x3f3f3f3f # define ll long long const int mod = 1e9 ; const int maxn = 100000+100; ll a[maxn]; ll ans[maxn]; ll dp[maxn][100]; ll n,m; int lowbit(int t) { return t&(-t); } void update(int t,int d) { while(t<=n) { a[t]=(a[t]+d)%mod; t+=lowbit(t); } } int query(int t) { ll ans=0; while(t>0) { ans=(ans+a[t])%mod; t-=lowbit(t); } return ans; } int main() { scanf("%lld %lld",&n,&m); for(int i=1; i<=n; i++) { scanf("%lld",&ans[i]); } for(int i=1; i<=n; i++) { dp[i][1]=1; } for( int i=2; i<=m; i++) { memset(a,0,sizeof(a)); for(int j=1; j<=n; j++) { dp[j][i]=(mod+query(n)-query(ans[j]))%mod;// 每一次尋找 update(ans[j],dp[j][i-1]); } } ll sum=0; for(int i=1; i<=n; i++) { sum=(sum+dp[i][m]+mod)%mod; } printf("%lld\n",sum); return 0; }