uoj 209 UER 6A 票數統計

2021-07-14 09:52:21 字數 1470 閱讀 3256

給出n個數,每個數是0或1.

再給出m個限制,每個限制(x,y)表示「前x個數中有y個1」或「後y個數中有x個1」

求這樣的序列的個數。

n<=5000,m<=1000

再一次被uer給虐了。

其實這道題劼鏼爺已經講的很清楚了。(撲通撲通跪下來)

當x!=y的時候,很顯然已經確定這個限制是限制字首還是字尾的。

當x=y的時候,我們只需要保留最大的那個x就行了。(顯然)

然後,我們可以用容斥。

答案是x=y是字首限制的個數+字尾限制的個數-前字尾都限制的個數。

那麼,現在就是有一堆前字尾的限制,讓你求方案數。

如果只有前(後)綴,那麼,就相當於把這n個數劃分成了m個區間,對於每乙個區間單獨限制。一堆組合數乘起來就好了。

那麼,前字尾都有的話,我們就可以把字尾轉化成字首。(反之亦然)

列舉1的總和就行了。

劼鏼**好!(刷隊形)

#include

#include

#include

#define fo(i,a,b) for(int i=a;i<=b;i++)

#define n 5005

using namespace std;

typedef long long ll;

const int mo=998244353;

struct notea[n],p[n];

bool cmp(note x,note y)

int c[n][n],n,m,ty,x,y,z,ans,tot;

int main()

for(scanf("%d",&ty);ty;ty--)

a[++tot].x=z;a[tot].y=z;a[tot].bz=0;a[tot].ty=1;

a[++tot].x=n-z;a[tot].y=z;a[tot].bz=1;a[tot].ty=2;

sort(a+1,a+tot+1,cmp);

fo(type,1,3)

fo(i,1,n)

if (p[cnt].x

y) if (p[cnt].x-p[cnt-1].x

y-p[cnt-1].y)

if (p[cnt].y-p[cnt-1].y

<0)

}if (pd) continue;int sum=1;

fo(j,1,cnt) sum=(ll)sum*c[p[j].x-p[j-1].x][p[j].y-p[j-1].y]%mo;

sum=(ll)sum*c[n-p[cnt].x][i-p[cnt].y]%mo;

if (type<=2) ans=(ans+sum)%mo;

else ans=(ans-sum+mo)%mo;

}printf("%d\n",(ans%mo+mo)%mo);

}}

UOJ 209 UER 6 票數統計

原題鏈結 妹滋滋是乙個善於程式設計的女孩子。但是某一天,她一不小心把 uoj 後台的票數統計程式寫錯了。本來嘛在這種根本沒有什麼用的功能上出了 bug 也沒有什麼大關係,但是又有某一天,uoj 突然就開始搞全民公投了。這可怎麼辦呢?如果這個訊息讓別人知道的話自己肯定會被查表,更不要說讓所有使用者重新...

UOJ 210 UER 6 尋找罪犯

有n個人分為好人和壞人,說了m句話。好人不會說假話,壞人至多說一句謊話。求出一組解,滿足要求。利用2 sat拆點,乙個人拆成兩個點,表示他是好人和壞人。然而這樣的話邊數是m 2的,所以用前 字尾和優化構圖即可。1 include 2 using namespace std 34 const int ...

uoj140 UER 4 被粉碎的數字

題目 看起來就像是數字 rm dp 不妨從豎式乘法的角度來考慮這個問題 為了方便處理進製,我們得從低位向高位填數 設 dp i 0 1 j p t 表示填到了第 i 位,卡不卡上界,f x j f k times x p 不計算最高位 需要向最高位進 t 的 x 有多少個 這裡的卡上界比較奇怪,如果...