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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

【THUSC2018】史莱姆之友【长链剖分】【链分治NTT】

發布時間:2023/12/4 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【THUSC2018】史莱姆之友【长链剖分】【链分治NTT】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

不知道這題能不能發出來,如果不能請聯系我,我什么都會做的

題意:給一棵 nnn 個結點的樹,每個結點有個 ax+bax+bax+b,求所有根到葉子的乘積之和。系數模 998244353998244353998244353。

鏈的情況就是分治 NTT,所以樹上沒有弱于這個的做法。

考慮鏈分治,先對樹做長鏈剖分,然后對根所在的鏈分治,維護兩個多項式,一個鏈上所有結點的乘積,一個從區間起點往下走,從區間中某個位置拐出去,走到所有葉子的路徑乘積之和。遞歸到分治樹的葉子的時候就遞歸算原樹上的輕兒子。

為了保證復雜度,NTT 的長度應該開當前區間所有虛兒子的最大深度和區間長度的較大值,而非區間起點的深度。這樣每條鏈只會在鏈頭的父親所在的鏈 分治的時候貢獻 O(log?n)\Omicron(\log n)O(logn) 次 NTT 的長度,總復雜度是 O(nlog?2n)\Omicron(n\log^2n)O(nlog2n),并且上界很松。

第一次寫封裝多項式,挺舒服的

#include <iostream> #include <cstdio> #include <cstring> #include <cctype> #include <vector> #define MAXN ((1<<18)+5) using namespace std; inline int read() {int ans=0;char c=getchar();while (!isdigit(c)) c=getchar();while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();return ans; } const int MOD=998244353; typedef long long ll; inline int add(const int& x,const int& y){return x+y>=MOD? x+y-MOD:x+y;} inline int dec(const int& x,const int& y){return x<y? x-y+MOD:x-y;} inline int qpow(int a,int p) {int ans=1;while (p){if (p&1) ans=(ll)ans*a%MOD;a=(ll)a*a%MOD,p>>=1;}return ans; } #define inv(x) qpow(x,MOD-2) int rt[2][24]; int r[MAXN],l,lim; inline void init(){lim=1<<l;for (int i=0;i<lim;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));} void ntt(int* a,int type) {for (int i=0;i<lim;i++) if (i<r[i]) swap(a[i],a[r[i]]);for (int L=0;L<l;L++){int mid=1<<L,len=mid<<1;int Wn=rt[type][L+1];for (int s=0;s<lim;s+=len){ll w=1;for (int k=0;k<mid;k++,w=w*Wn%MOD){int x=a[s+k],y=w*a[s+mid+k]%MOD;a[s+k]=add(x,y),a[s+mid+k]=dec(x,y);}}}if (type){int t=inv(lim);for (int i=0;i<lim;i++) a[i]=(ll)a[i]*t%MOD;} } struct poly {int *a,n;inline poly():n(0){}inline poly(int x):n(x){a=new int[x];memset(a,0,sizeof(int)*n);}inline poly(int x,int y):n(2){a=new int[2];a[0]=x,a[1]=y;}inline int& operator [](const int& i){return a[i];}inline const int& operator [](const int& i)const{return a[i];} }; inline poly operator *(const poly& a,const poly& b) {static int ta[MAXN],tb[MAXN];poly c(a.n+b.n-1);for (l=0;(1<<l)<c.n;++l);init();for (int i=0;i<lim;i++) ta[i]=tb[i]=0;for (int i=0;i<a.n;i++) ta[i]=a[i];for (int i=0;i<b.n;i++) tb[i]=b[i];ntt(ta,0),ntt(tb,0);for (int i=0;i<lim;i++) ta[i]=(ll)ta[i]*tb[i]%MOD;ntt(ta,1);for (int i=0;i<c.n;i++) c[i]=ta[i];return c; } inline poly operator +(const poly& a,const poly& b) {poly c(max(a.n,b.n));for (int i=0;i<c.n;i++) c[i]=add(i<a.n? a[i]:0,i<b.n? b[i]:0);return c; } vector<int> e[MAXN]; int buf[MAXN],*tp=buf; int fa[MAXN],son[MAXN],mx[MAXN]; int *lis[MAXN]; inline int* newbuf(int x){int* p=tp;tp+=x;return p;} void dfs(int u,int f) {fa[u]=f;for (int i=0;i<(int)e[u].size();i++)if (e[u][i]!=f){dfs(e[u][i],u);if (mx[e[u][i]]>mx[son[u]]) son[u]=e[u][i];}mx[u]=mx[son[u]]+1; } void dfs(int u,int* cur) {*(lis[u]=cur)=u;if (son[u]) dfs(son[u],cur+1);for (int i=0;i<(int)e[u].size();i++)if (e[u][i]!=fa[u]&&e[u][i]!=son[u])dfs(e[u][i],newbuf(mx[e[u][i]])); } int rval[MAXN],gval[MAXN]; pair<poly,poly> solve(int* L,int* R) {if (L==R){int u=*L;poly tmp;for (int i=0;i<(int)e[u].size();i++)if (e[u][i]!=fa[u]&&e[u][i]!=son[u])tmp=tmp+solve(lis[e[u][i]],lis[e[u][i]]+mx[e[u][i]]-1).second;if ((int)e[u].size()==(fa[u]>0)) tmp=poly(1),tmp[0]=1;return make_pair(poly(rval[u],gval[u]),poly(rval[u],gval[u])*tmp);}int* mid=L+((R-L)>>1);pair<poly,poly> lans=solve(L,mid),rans=solve(mid+1,R);return make_pair(lans.first*rans.first,lans.first*rans.second+lans.second); } poly ans; int main() {freopen("slime.in","r",stdin);freopen("slime.out","w",stdout);rt[0][23]=qpow(3,119),rt[1][23]=inv(rt[0][23]);for (int i=22;i>=0;i--){rt[0][i]=(ll)rt[0][i+1]*rt[0][i+1]%MOD;rt[1][i]=(ll)rt[1][i+1]*rt[1][i+1]%MOD;}int n=read();read();for (int i=1;i<=n;i++) rval[i]=read();for (int i=1;i<=n;i++) gval[i]=read();for (int i=1;i<n;i++){int u,v;u=read(),v=read();e[u].push_back(v),e[v].push_back(u);}dfs(1,0);dfs(1,newbuf(mx[1]));ans=solve(lis[1],lis[1]+mx[1]-1).second;for (int i=0;i<=n;i++) printf("%d\n",(i<ans.n? ans[i]:0));return 0; }

總結

以上是生活随笔為你收集整理的【THUSC2018】史莱姆之友【长链剖分】【链分治NTT】的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 人人爽人人爽人人 | 伊人青青草| 精品1卡二卡三卡四卡老狼 日韩三级网 | 国产三级小视频 | 国产成人一区二区三区视频 | 人物动物互动39集免费观看 | 成人精品免费在线观看 | 丰满少妇在线观看bd | 日本一级大片 | 精品国产黄色 | 中文字幕在线观看不卡 | 日本成人片在线 | 一级黄色在线播放 | 91视频青青草 | 91精品国产麻豆国产自产在线 | 天天干天天要 | 青青草原av在线 | 日本人妻伦在线中文字幕 | 制服丝袜影音先锋 | 亚洲一区二区视频网站 | 性欧美日本| 成人性免费视频 | 成人免费大片黄在线播放 | 成人免费在线网址 | wwwwww日本| 国产91一区二区三区在线精品 | 亚洲av成人精品一区二区三区在线播放 | 欧美一区二区三区在线播放 | 国产一区欧美二区 | 黄色网久久 | 亚洲综合av网 | 日韩免费在线观看 | 日韩精品一区二区av | 中文字幕人妻互换av久久 | 在线免费日本 | 黄色网av | av毛片在线播放 | 日韩av不卡在线 | 免费久草视频 | 久久久久久久久久成人 | 日本后进式猛烈xx00动态图 | 亚洲一区国产精品 | 美女被出白浆 | 免费成年人视频在线观看 | 伊人午夜 | 玩弄白嫩少妇xxxxx性 | 99热激情| 午夜小视频网站 | 四虎激情 | 国产冒白浆 | 国产自偷自拍 | 91精品国产综合久久香蕉 | 久久理伦 | 青娱网电信一区电信二区电信三区 | 成人午夜精品一区二区三区 | 免费激情小视频 | 操操网站 | 国产一区视频在线免费观看 | 波多野吉衣毛片 | 国产三级做爰高清在线 | 国产91在线精品 | 午夜婷婷 | 亚洲一区二区伦理 | av收藏小四郎最新地址 | 国产又黄又大又爽 | 亚洲综合日韩精品欧美综合区 | 男人天堂a在线 | av尤物 | 久久黄色网络 | 五月婷婷综 | 特级淫片裸体免费看 | 国产精品无码粉嫩小泬 | 国产短视频一区 | 最近免费中文字幕大全免费版视频 | 视频在线观看网站免费 | 高清乱码毛片入口 | 懂色av,蜜臀av粉嫩av | 日本精品一区二区三区四区 | 黑人巨大精品人妻一区二区 | 狠狠操在线观看 | 婷婷国产| 视频一区二区三区在线观看 | 欧美日韩精品一区 | 男人靠女人免费视频网站 | 成人一区二区三区在线观看 | 中文字幕日韩一区二区三区不卡 | 精品三级在线观看 | 日本福利小视频 | 性网址 | 亚洲av毛片成人精品 | 亚洲欧美日韩精品永久在线 | 国产一区二区三区精品在线 | 91丝袜一区在线观看 | 日本欧美国产一区二区三区 | 亚洲一区二区三区激情 | 亚洲v欧美v另类v综合v日韩v | 天堂网站 | 日本va在线 | 精品国产99久久久久久 |