牛客提高訓練營2B 分糖果

2022-03-26 21:06:15 字數 2872 閱讀 6729

題目

發現自己一年之前非常垃圾

題目大意是給你乙個\(n\)個點的環,給每個點乙個\([1,a_i]\)的取值,並且滿足環上任意相連兩點權值不能相等,求方案數

考慮斷環為鏈,發現不大會

不妨考慮所有\(a_i\)均相等的情況,設\(m=a_i\)

對於第乙個點,有\(m\)種選擇,其後每乙個點的取值都不能和上乙個相等,即\(m-1\)種選擇,於是整個環就是\(m(m-1)^\)

嗎?顯然不是,這樣我們不能保證\(1\)號點和\(n\)號點的取值不相等。設\(f_i\)表示\(1\)號點恰好和\(n-i+1\)到\(n\)號點取值相等的情況,我們算的\(m(m-1)^\)其實等於\(f_0+f_1\)

考慮如何消掉\(f_1\),我們可以強行將\(n\)和\(1\)取值相同,其餘點還是不能和前乙個點取值相等,方案數是\(m(m-1)^=f_1+f_2\);更一般的\(m(m-1)^=f_+f_i\),但是有乙個特殊情況,即\(m(m-1)=f_\),即讓\(3\)號點到\(n\)號點都和\(1\)號點取值相等,這樣\(2\)號點和\(1\)不相同自然就不會和後面的點相同。

我們要求的是\(f_0\),我們發現\(f_0+f_1-(f_1+f_2)+f_2+f_3-....-f_+f_=f_0\),即我們配乙個\(-1\)的容斥係數即能求出\(f_0\)。

於是我們利用這個容斥就能斷環為鏈,所以我們來考慮更一般的鏈上問題,即\(a_i\)不同的情況。

有乙個顯然的暴力\(dp\),設\(dp_\)表示第\(i\)個點取值為\(j\)的方案數,\(s_i=\sum_^dp_\),轉移顯然有\(dp_=s_-dp_\)

由於我們的容斥本質上是使得最後連續的一段和\(1\)取值相等,這一段連續的取值受限於這一段中\(a_i\)的最小值,於是我們不妨選乙個\(a_i\)最小的點作為一號點,這樣每次\(dp\)的初值就不會改變,只需做一次\(dp\)即可。

考慮優化這個\(dp\)

當\(a_i>a_\)的時候,對於\(\forall j\in [1,a_]\)有\(dp_=s_-dp_\);當\(j>a_\)的時候,由於\(dp_=0\),所以對於\(j\in(a_,a_i]\)有\(dp_=s_\)

當\(a_的時候,對於\(\forall j\in [1,a_]\)有\(dp_=s_-dp_\);當\(j>a_i\)的時候,則有\(dp_=0\)

不難發現這幾個轉移我們只需要乙個能夠支援區間取反、區間加以及區間覆蓋的資料結構就能維護,於是直接使用線段樹來整體dp即可。

由於\(a_i\)比較大,所以得動態開點,複雜度是\(o(n\log a_i)\)只能有\(80pts\)

**

#include#define re register

#define max(a,b) ((a)>(b)?(a):(b))

#define min(a,b) ((a)<(b)?(a):(b))

#pragma gcc optimize(3)

#pragma gcc optimize("-fcse-skip-blocks")

inline int read()

const int mod=1e9+7;

const int m=7e7+5;

const int maxn=1e6+5;

int n,a[maxn],f[maxn],b[maxn],pos,mx,rt;

inline int qm(int x)

int l[m],r[m],gt[m],jt[m],sum[m],cnt;

bool ft[m];

inline void pushdown(int now,int lx,int ry)

if(ft[now])

if(jt[now])

}int gan(int now,int x,int y,int lx,int ry,int v)

pushdown(now,lx,ry);

int mid=lx+ry>>1;

if(x<=mid) l[now]=gan(l[now],x,y,lx,mid,v);

if(y>mid) r[now]=gan(r[now],x,y,mid+1,ry,v);

sum[now]=qm(sum[l[now]]+sum[r[now]]);

return now;

}int jia(int now,int x,int y,int lx,int ry,int v)

pushdown(now,lx,ry);

int mid=lx+ry>>1;

if(x<=mid) l[now]=jia(l[now],x,y,lx,mid,v);

if(y>mid) r[now]=jia(r[now],x,y,mid+1,ry,v);

sum[now]=qm(sum[l[now]]+sum[r[now]]);

return now;

}int qufan(int now,int x,int y,int lx,int ry)

pushdown(now,lx,ry);

int mid=lx+ry>>1;

if(x<=mid) l[now]=qufan(l[now],x,y,lx,mid);

if(y>mid) r[now]=qufan(r[now],x,y,mid+1,ry);

sum[now]=qm(sum[l[now]]+sum[r[now]]);

return now;

}int main()

for(re int i=1;i<=n;i++) mx=max(mx,a[i]);

f[1]=b[1];rt=gan(rt,1,b[1],1,mx,1);

for(re int i=2;i<=n;++i)

正解也就是容斥+dp,但是容斥方法好像不太一樣,就直接丟鏈跑了

正解

牛客提高訓練營5B 旅遊

題目 吉老師的題時過一年還是不會做 從 1 號點出發經過每條邊至少一次並且還要回到 1 號點,這跟尤拉迴路的條件非常像,但是尤拉迴路的實際上是 經過每一條邊恰好一次並且回到出發點 所以可以理解為將每一條邊拆成多條邊,使得總邊權和最小,並且圖中存在一條尤拉迴路 而一張圖存在尤拉迴路的條件是不存在度數為...

NOIP訓練營內部試題 分糖果

noip訓練營內部試題 分糖果 摘自 清北學堂noip訓練營試題t2 題目 分糖果 分糖果 candy time limit 1000ms memory limit 128mb 題目描述 總共有n顆糖果,有3個小朋友分別叫做l,y,k。每個小朋友想拿到至少k顆糖果,但這三個小朋友有乙個共同的特點 對...

牛客提高訓練營5A 同餘方程

題目 吉老師的題做不動啊 首先 l 1,r 1 l 2,r 2 並不是非常好做,我們考慮將其拆成字首資訊 設 solve n,m sum n sum m m i bigoplus j 於是我們的答案就變成了 solve r 1,r 2 solve l 1 1,r 2 solve r 1,l 2 1 ...