F2。テスト233の間違った回答(ハード版)
あなたのプログラムが再び失敗します。今回はそれが「テスト233に間違った答えを」取得します
。
これは、問題の難しいバージョンです。このバージョンでは、1≤n≤2⋅105。あなたはそれをロックした場合は、この問題をハックすることができます。しかし、あなたは両方の問題をロックした場合にのみ、以前の問題をハックすることができます。
問題は、n一選択肢-質問を終了することです。質問のそれぞれは、k個のオプションが含まれており、いずれか一方のみが正しいです。i番目の質問への答えがhiである、と私はハイテクで、質問のあなたの答えは、あなたが1ポイントを獲得すれば、そうでない場合、あなたはこの質問のために0ポイントを獲得します。値はH1、H2、...、HNは、この問題であなたに知られています。
しかし、あなたはあなたのプログラムに誤りがあります。それは答えを時計回りに移動します!答えは、円の中に書かれているすべてのnを考えてみましょう。あなたのプログラムの誤りに起因して、それらが周期的に1つシフトしています。
正式には、間違いが質問imodn + 1に質問私のための答えを移動します。質問2への質問1、質問3への質問2のための答え、...、質問のためのnは、質問1の答えのための答えを移動させ、それはそう。
我々は、すべて一緒に、n個の解答解答スーツを呼び出します。合計KN可能な答えのスーツがあります。
1で時計回りに移動した後、新しい応答スーツのポイントの合計数は、古いもののポイント数よりも厳密に大きい:あなたは多くの回答スーツには、以下の条件を満足するか、迷っています。あなたは答えを法998244353を見つける必要があります。
たとえば、= 5、およびあなたの答えのスーツのn場合= [1,2,3,4,5]は、それが原因のミスで[5,1,2,3,4] = 'として提出されますです。正解スーツは、H = [5,2,2,3,4]、1ポイントを獲得応答スーツと回答スイートAが '4ポイントを稼いでいます。> 1 4ので、回答スーツA = [1,2,3,4,5]はカウントされるべきです。
入力
質問の数と各質問に対する可能な答えの数 - 最初の行は二つの整数N、K(1≤n≤2⋅105、1≤k≤109)が含まれています。
次の行は、nは整数H1、H2、...、HN、(1≤hi≤k)含まれています - 質問に対する回答を。
出力
出力1つの整数:与えられた条件を満足する答えスーツの数、剰余998244353。
例
入力
3 3
1 3 1
の出力
9
入力
5
1 1 4 2 2
出力
1000年
入力
6 2
1 1 2 2 1 1
出力
16
注意
最初の例では、有効な回答のスーツは、[2,1,1]、[2,1,2]、[2,1,3]、[3,1,1]、[3,1,2]、[ 3,1,3]、[3,2,1]、[3,2,2]、[3,2,3]。
問題の意味
n個の質問がありますが、それぞれの質問には、k個の答えを持っていますが、あなたは愚かな今、最初の質問への答えは2番目の質問、2番目の質問は、3番目の質問を参照して、2番目の質問は最初のkと呼ばれていました(k個%と呼ばn)の位置+1までのタイトル。
正しい番号が答えを埋めるためのプログラムがあるどのように多くの、知っていただきたいと思います、あなたは、交換前のより正確な量よりも交換を行うことができます。
問題の解決策
データ・ワード、DP [i] [j]の小さな範囲は、i番目の今の質問に与えられ、前のJ交換分より少しの交換後を示しています。
次いで、Hなら[I] == H [I + 1]、その後、DP [I] [J] = DP [I-1] [j]は、のようにいずれの場合に充填されたならないものの正しい数を有しています。
その他の場合は、DP [I] [J] = DP [I-1] [J + 1] + DP [I-1] [J-1] +(K-2)DP [I-1] [j]は、変換が間違っていた後の場合は、前である、間違った前、変換後、回答の他のK-2種類が同じままです。
ハードバージョンは、我々は^、の反対を行う私たちが知っていると言うと、最後のANSを変換する変換プログラムの前にポイント数が同じ場合、kにしたいのn-ANSプログラム変更の数の換算スコアを表します。
フロント及び高い変換画分とは、プログラム番号の高いスコアを変換するため、対称性の、最終的な答えがなければならないので、同じである(K ^ N-ANS)/ 2
今H [i]のを想定し、それを行うにはどのようにこのANSはそう!=それが何で満たしていないため、同じ言葉が、意味がないので、時間の数[I + 1]はNUMです
我々は、位置+1の番号を列挙し、C(NUM、i)は、それらが同じi番目-1(NUM-I、I)Cは、NUM-2I他の位置が選択肢を持っを有するK-2( - K- 2)^(NUM-2I)、残りのn-NUM選択位置は、K K ^(N-NUM)を有します。
次いで、I + 1位の番組の数は、実際にはC(NUM、I)、C(NUM-I、I)、(K-2)^(NUM-2I)K ^(N-NUM)、および全部でプログラムの最後に数であります彼が差し引かれ、逃げるために2で割りました。
コード:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2005;
const int mod = 998244353;
int h[maxn];
long long dp[maxn][maxn*2],base=2003,k,n;
int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
scanf("%d",&h[i]);
if(k==1){
cout<<"0"<<endl;
return 0;
}
dp[0][base]=1;
for(int i=1;i<=n;i++){
for(int j=base-2000;j<=base+2000;j++){
if(h[i]==h[i%n+1]){
dp[i][j]=dp[i-1][j]*k%mod;
}else{
dp[i][j]=(dp[i-1][j+1]+dp[i-1][j-1]+dp[i-1][j]*(k-2))%mod;
}
}
}
long long ans = 0;
for(int i=1;i<=n;i++){
ans=(ans+dp[n][base+i])%mod;
}
cout<<ans<<endl;
}
#include<bits/stdc++.h>
using namespace std;
const long long mod = 998244353;
const int maxn = 2e5+7;
int n,k,h[maxn];
long long powmod(long long a,long long b){
if(b==0)return 1;
return b%2==0?powmod(a*a%mod,b/2):powmod(a*a%mod,b/2)*a%mod;
}
long long fac[maxn],inv[maxn];
long long C(int a,int b){
if(b<0||b>n)return 0;
return (fac[a]*inv[b]%mod)*inv[a-b]%mod;
}
int main(){
fac[0]=inv[0]=1;
for(int i=1;i<maxn;i++){
fac[i]=i*fac[i-1]%mod;
inv[i]=powmod(i,mod-2)*inv[i-1]%mod;
}
cin>>n>>k;
if(k==1){
cout<<"0"<<endl;
return 0;
}
for(int i=0;i<n;i++)
cin>>h[i];
int num = 0;
h[n]=h[0];
for(int i=0;i<n;i++){
if(h[i]!=h[i+1])num++;
}
long long ans = 0;
for(int i=0;i*2<=num;i++){
long long tmp = C(num,i)*C(num-i,i)%mod*powmod(k-2,num-2*i)%mod*powmod(k,n-num);
ans=(ans+tmp)%mod;
}
cout<<((powmod(k,n)-ans+mod)*inv[2])%mod<<endl;
}