Luo Gu [5368] [PKUSC2018] real rankings (combinatorics)

Click here to see the problem surface

Generally meaning of problems: there are \ (n-\) digits, define a ranking number is not less than the number of its number. Which will now be random \ (k \) number multiplied by \ (2 \) , find how many kinds of programs make it the same rank for each number.

Category talk

For this problem, we can talk about classification, assuming that the current account of the \ (i \) answer number.

When \ (a_i \) is not to be modified since it was originally \ (\ ge a_i \) number can not be modified after the \ (<a_i \) , so we can know:

  • Originally it \ (\ ge a_i \) number can be freely modified.
  • Original \ (<a_i \) after the number if you modify \ (\ ge a_i \) can not be altered.

If we sort the original sequence, provided \ (T1 \) satisfies \ (2a_ {T1} <a_i \ Le 2a_ T1 +. 1 {} \) , then there may not modify the number \ (i-t1 \) a, while the remaining \ (n- (i-t1) \) number can be modified, i.e., the number of programs:

\ [C_ {n (i-t1)} k ^ \]

When \ (a_i \) is modified, because originally it \ (<a_i \) number after modifying the inevitable still \ (<a_i \) , so we can know:

  • Originally it \ (<a_i \) number can be freely modified.
  • Originally it \ (\ ge2a_i \) number can be freely modified.
  • Original \ (\ ge a_i \) and \ (<2a_i \) number must be modified.

If we sort the original sequence, provided \ (T2 \) satisfies \ (T2 A_ {} <2a_i \ A_ Le T2 +. 1 {} \) , then there must be modified number \ (t2-i + 1 \ ) one (Note that \ (a_i \) must be modified), the remaining \ (n- (t2-i + 1) \) number can be modified, i.e., the number of programs:

\[C_{n-(t2-i+1)}^{k-(t2-i+1)}\]

For \ (T1, T2 \) , we can enumerate (i \) \ maintenance at the same time.

Special cases

Note that there are two special cases will the above reasoning card out.

  • \(a_i=0\)
    • Question: We find that, according to \ (t2 \) is defined, in which case \ (T2 <i \) , will pan.
    • Solution: each time the \ (T2 \) to \ (I \) takes \ (max \) .
  • Appear the same \ (a_i \) .
    • Question: In the course of the discussion will pan on some of the details of the border.
    • Solution: difficult to find, the same \ (a_i \) The answer is the same. For some of the same \ (a_i \) , wherein the first \ (a_i \) is calculated by the above method is not answer error. So will all the same \ (a_i \) answers Ode for the first \ (a_i \) answer to.

Code

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg 
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 100000
#define X 998244353
#define C(x,y) ((x)>=(y)?1LL*Fac[x]*IFac[y]%X*IFac[(x)-(y)]%X:0)
using namespace std;
int n,k,ans[N+5],Fac[N+5],IFac[N+5];
struct data {int p,v;I bool operator < (Con data& o) Con {return v<o.v;}}s[N+5];
I int Qpow(RI x,RI y) {RI t=1;W(y) y&1&&(t=1LL*t*x%X),x=1LL*x*x%X,y>>=1;return t;}
int main()
{
    RI i,t1,t2,lst;for(scanf("%d%d",&n,&k),Fac[0]=i=1;i<=n;++i) Fac[i]=1LL*Fac[i-1]*i%X;//预处理阶乘
    for(IFac[n]=Qpow(Fac[n],X-2),i=n-1;~i;--i) IFac[i]=1LL*IFac[i+1]*(i+1)%X;//预处理阶乘逆元
    for(i=1;i<=n;++i) scanf("%d",&s[s[i].p=i].v);//读入
    for(sort(s+1,s+n+1),s[0].v=-1,i=1,t1=t2=0;i<=n;++i)//记得排序
    {
        if(s[i].v==s[i-1].v) {ans[s[i].p]=lst;continue;}//如果与上一个数一样
        W(t1^n&&2*s[t1+1].v<s[i].v) ++t1;W(t2^n&&s[t2+1].v<2*s[i].v) ++t2;t2<i&&(t2=i);//更新t1,t2
        ans[s[i].p]=lst=(C(n-(i-t1),k)+(t2-i<=k?C(n-(t2-i+1),k-(t2-i+1)):0))%X;//计算答案
    }
    for(i=1;i<=n;++i) printf("%d\n",ans[i]);return 0;//输出答案
}

Guess you like

Origin www.cnblogs.com/chenxiaoran666/p/Luogu5368.html