並不對勁的馬後炮1210

2022-05-08 20:27:08 字數 4472 閱讀 4988

題目大意

有乙個有\(n\)(\(n\leq152501\))個節點的有向圖,每個節點的出度和入度都是\(1\),隨機選擇不重複的\(k\)個點,求從這\(k\)個點出發,能走到每乙個點的概率,模998244353

題解發現\(n\)個點中選\(k\)個共有\(c_^\)個方案,那麼只要求出有多少種選點方案使從選中的點能走到每乙個點,就能用這個方案數除以\(c_^\)得到答案

每個節點的出度和入度都是\(1\)的有向圖只由若干個環組成,設一共有\(m\)個環

所以當且僅當每乙個環上都存在乙個選中的點時,能從選中的點走到每乙個點

設\(f(i,j)\)表示考慮前\(i\)個環,選\(j\)個點,能使每個環上都有選中的點的方案數,\(siz(i)\)表示第\(i\)個環上有幾個點

則有\[f(i,j)=\sum_^f(i-1,x)*c_^x

\]設函式$$g_i(x)= 0*x0+\sum_c_j*xj $$

設函式\(h_i(x)\),\(j\)次項的係數為\(f(i,j)\)

則\(h_i\)為\(h_\)和\(g_i\)的卷積

那麼方案數就變成了將\(g_1\),\(g_2\),……,\(g_m\)都卷起來後,\(k\)次項的係數

發現直接暴力將相鄰的兩個卷起來可能會被卡

可以像哈夫曼樹那樣合併,或進行分治,算出前一半和後一半結果後將這兩個結果卷起來

**我寫的是分治的做法

#include#include#include#include#include#include#include#include#include#include#include#include#include#include#define rep(i,x,y) for(int i=(x);i<=(y);++i)

#define dwn(i,x,y) for(int i=(x);i>=(y);--i)

#define maxn 152510

#define maxm (maxn<<3)

#define ll long long

using namespace std;

int read()

void write(int x)

int f=0;char ch[20];

if(x<0)putchar('-'),x=-x;

while(x)ch[++f]=x%10+'0',x/=10;

while(f)putchar(ch[f--]);

putchar('\n');

return;

}const ll mod=998244353;

int n,k,m,r[maxm],len,t,p[maxn],inv[maxn],po[maxn],siz[maxn];

int a[maxm],b[maxm],cnt,vis[maxn],g[maxn],ing[maxn],nowlen,nown;

int c(int x,int y)

int mul(int x,int y)

return ans;

}void fntt(int * c,int f)

int getsiz(int u)

void getans(int l,int r)

return;

} int mid=(l+r)>>1,lim1,lim2;

getans(l,mid),getans(mid+1,r);

lim1=v[l].size(),lim2=v[mid+1].size();

rep(i,0,lim1-1)a[i]=v[l][i];

rep(i,0,lim2-1)b[i]=v[mid+1][i];nowlen=0,nown=1;

while(nown-1題目大意

有乙個列數為\(m\)(\(m\leq8\))的方格圖,有\(s1\)種顏色的\(1*2\)的地磚,\(s2\)種顏色的\(2*1\)的地磚,\(f(x)\)表示當方格圖行數為\(x\)時,將整個方格圖鋪滿有多少種方案

給出\(l,r\)(\(l\leq r\leq10^\)),求\(f(l)+f(l+1)+...+f(r-1)+f(r)\)模998244353

題解前置知識不會,先坑著

**只會80分矩乘

#include#include#include#include#include#include#include#include#include#include#include#include#include#include#define rep(i,x,y) for(register int i=(x);i<=(y);++i)

#define dwn(i,x,y) for(register int i=(x);i>=(y);--i)

#define maxs ((1<<8)+3)

#define maxlen 2510

#define ll long long

using namespace std;

int read()

void write(int x)

int f=0;char ch[20];

if(x<0)putchar('-'),x=-x;

while(x)ch[++f]=x%10+'0',x/=10;

while(f)putchar(ch[f--]);

putchar('\n');

return;

}const ll mod=998244353;

int vis[maxs],sta[maxs],cnt,ans[2][maxs],to[maxs][maxs],tmpans[maxs],tmp[maxs][maxs],tmp2[maxs][maxs],t***[maxs][maxs];

int num[2][maxlen],len[2],m,s1,s2;

int mul(int x,int y)

return ans;

}void getst(int id,int step,int nowst,int cnt1,int cnt2)

if((sta[id]&(1《題目大意

有一棵有\(n\)(\(n\leq152501\))節點的樹,有邊權、點權,共有\(q\)(\(q\leq152501\))次操作,支援兩種操作:

1.修改乙個點的點權

2.給出兩點\(x,y\),要在\(x,y\)之間的簡單路徑上找乙個點\(u\),使得\(x,y\)之間的簡單路徑上其他點的點權乘該點到點\(u\)的距離之和最小,輸出最小值

保證2操作的結果不超過\(10^\)

題解先坑著

**#include#include#include#include#include#include#include#include#include#include#include#include#include#include#define rep(i,x,y) for(register int i=(x);i<=(y);++i)

#define dwn(i,x,y) for(register int i=(x);i>=(y);--i)

#define maxn 152510

#define ll long long

using namespace std;

int read()

void write(ll x)

int f=0;char ch[20];

if(x<0)putchar('-'),x=-x;

while(x)ch[++f]=x%10+'0',x/=10;

while(f)putchar(ch[f--]);

putchar('\n');

return;

}int dfn[maxn],tim,siz[maxn],n,q;

int fir[maxn],nxt[maxn<<1],v[maxn<<1],cnt,anc[maxn][20];

ll w[maxn<<1],dep[maxn],dep0[maxn],s[2][maxn],a[maxn],ans;

void ade(int u1,int v1,ll w1)

int lt(int x)

void add(int x,ll y,int f)

ll ask(int x,int f)

void getanc(int u)

int lca(int x,int y)

ll getdis(int x,int y,int lca,int u)

void work(int x,int y,int lca)

} }if(tx!=lca)getdis(x,y,lca,anc[tx][0]);

return;

}int main()

getanc(1);

rep(i,1,n)add(dfn[i],a[i],0),add(dfn[i]+siz[i],-a[i],0),add(dfn[i],a[i]*dep[i],1),add(dfn[i]+siz[i],-a[i]*dep[i],1);

q=read();

while(q--)

else

}return 0;

}

並不對勁的splay

splay和不加任何旋轉一定會被卡的二叉搜尋樹的唯一區別就是每次操作把當前節點旋轉到根。旋轉有各種zig zag的組合方式,感覺很麻煩,並不對勁的人並不想講。其實可以找出一些共性將它們合併。設ls a 點a是其父親的左兒子 son a 0 a的左兒子,son a 1 a的右兒子,fa a a的父親。...

並不對勁的費用流

最小費用最大流肯定要保證最大流,所以它和最大流有一些類似的性質。如果把費用看成邊,就可以每次走最短路 保證費用最小 走到不能走為止 保證最大流 費用流版的ek就是這樣。需要注意的是,反向弧的邊權為它對應的正向弧的費用的相反數,所以最短路要用spfa來求。費用流版的dinic,又叫zkw費用流,還是多...

並不對勁的字尾陣列

字尾陣列sa x 表示排序後第x位在排序前的位置。這個東西的求法有兩種,一種是倍增,時間複雜度o n log n 或o n log2n 另一種是用不知道什麼方法做到的o n 至於第二種方法是什麼,並不對勁的人並不知道,所以只說倍增。考慮正常地比較兩個字串,都是從頭比較到尾 那麼,如果把兩個字串都斷成...