日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Codeforces 1188E Problem from Red Panda (计数)

發布時間:2025/3/15 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Codeforces 1188E Problem from Red Panda (计数) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目鏈接

https://codeforces.com/contest/1188/problem/E

題解

我們可以發現,題目要求數的目標狀態的個數,實際上就是在數操作序列(指每個氣球操作的次數構成的序列,第 \(i\) 個顏色操作 \(b_i\) 次)的個數。可以發現如果給定了操作序列,每次一定是操作那個剩下的 \(a_i\) 最小的。那么對于一個合法序列 \(b\),將其每個元素減去 \(1\) 后一定合法,且得到的序列不變。那么我們可以通過強制至少一個 \(b_i=0\) 來保證不算重。
然后我就卡住了。。。。。手動再見
考慮每種顏色對序列合法的限制,就是對每個 \(i\),前 \(a_i+mk+1 (m=0,1,2,...)\) 次操作至少要有一次操作 \(i\). 那么從小到大枚舉操作總數 \(s\) (\(0\le s\le \max a_i\)),我們可以得到某些必須進行的操作,剩余的操作分配給 \(k\) 種顏色,使用插板法計算。為了保證存在 \(b_i=0\),再減去強制給每個未出現限制的 \(b_i\)\(+1\) 的方案數。
時間復雜度 \(O(k+\max a_i)\).

代碼

#include<bits/stdc++.h> #define llong long long #define mkpr make_pair #define iter iterator #define riter reversed_iterator #define y1 Lorem_ipsum_dolor using namespace std;inline int read() {int x = 0,f = 1; char ch = getchar();for(;!isdigit(ch);ch=getchar()) {if(ch=='-') f = -1;}for(; isdigit(ch);ch=getchar()) {x = x*10+ch-48;}return x*f; }const int mxN = 1e6; const int P = 998244353; llong fact[mxN*2+3],facti[mxN*2+3]; int a[mxN+3]; int cnt[mxN+3],cnt2[mxN+3]; int n,mx;llong quickpow(llong x,llong y) {llong cur = x,ret = 1ll;for(int i=0; y; i++){if(y&(1ll<<i)) {y-=(1ll<<i); ret = ret*cur%P;}cur = cur*cur%P;}return ret; } llong comb(llong x,llong y) {return x<0||y<0||x<y?0ll:fact[x]*facti[y]%P*facti[x-y]%P;}void updsum(llong &x,const llong y) {x = x+y>=P?x+y-P:x+y;}void initfact(int n) {fact[0] = 1ll; for(int i=1; i<=n; i++) fact[i] = fact[i-1]*i%P;facti[n] = quickpow(fact[n],P-2); for(int i=n-1; i>=0; i--) facti[i] = facti[i+1]*(i+1ll)%P; }int main() {initfact(mxN*2);n = read();for(int i=1; i<=n; i++) a[i] = read(),mx = max(mx,a[i]);for(int i=1; i<=n; i++){for(int j=a[i]+1; j<=mx; j+=n) {cnt[j]++;} cnt2[a[i]+1]++;}llong ans = 0ll;for(int i=0,j=0,k=n; i<=mx; i++,j++){j-=cnt[i],k-=cnt2[i]; // printf("i=%d j=%d k=%d\n",i,j,k);if(j<0) break;llong tmp = comb(j+n-1,n-1);updsum(ans,tmp);if(j-k>=0){llong tmp = comb(j-k+n-1,n-1);updsum(ans,P-tmp);}}printf("%I64d\n",ans);return 0; }

總結

以上是生活随笔為你收集整理的Codeforces 1188E Problem from Red Panda (计数)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。