2024.11.10 鲜花
Triple 扩展
像神一样呐
愛のネタバレ 「別れ」っぽいな 人生のネタバレ 「死ぬ」っぽいな なにそれ意味深で かっこいいじゃん それっぽい単語集で踊ってんだ 失敬 とぅ とぅる とぅ とぅ とぅる “風” とぅ とぅる とぅ とぅ とぅる “風” とぅ とぅる とぅ とぅ とぅる “風” ぽいじゃん ぽいじゃん とぅ とぅる とぅ とぅ とぅる “風” とぅ とぅる とぅ とぅ とぅる “風” とぅ とぅる とぅ とぅ とぅる 神っぽいな もういいぜ もういいぜ それ もういいぜ もういいぜ 逆に興奮してきたなあ おっきいね おっきいね 夢 おっきいね おっきいね 景気いいけど 品性はthe end うええい うええい "Gott ist tot" 神っぽいな それ 卑怯 神っぽいな それ "my god" アイウォンチュー ウォンチュー IQが下がっていく感じ 邪心ぽいな それ 畢竟 邪心ぽいな それ "my god" アイヘイチュー ヘイチュー 害虫はどっち その髪型 その目 その口元 その香水 その服 そのメイク アレっぽいな それ 比況 アレっぽいな それ その名言 その意見 その批評 そのカリスマ そのギャグ そのセンス 神っぽいな それ 卑怯 ぽいな ぽいな ぽい 憧れちゃう とぅ とぅる とぅ とぅ とぅる “風” とぅ とぅる とぅ とぅ とぅる “風” とぅ とぅる とぅ とぅ とぅる “風” ぽいじゃん ぽいじゃん とぅ とぅる とぅ とぅ とぅる “風” とぅ とぅる とぅ とぅ とぅる “風” とぅ とぅる とぅ とぅ とぅる 神っぽいな メタ思考する本質は悪意? 人を小馬鹿にしたような作為 無為に生き延びるのは難しい 権力に飲まれて揺らぐ灯り 神を否定し神に成り代わり 玉座で豹変する小物達 批判に見せかけ自戒の祈り Do you know? 何言ってんの? それ ウザい 何言ってんの? それ 意味がよくわかんないし 眠っちゃうよ マジ 飽きっぽいんだ オーケー みんな 飽きっぽいんだ オーケー 踊れるやつ ちょうだい ちょうだい ビーム きっしょいね きっしょいね それ きっしょいね きっしょいね 逆にファンになってきたじゃん ちっちゃいね ちっちゃいね 器 ちっちゃいね ちっちゃいね 天才ゆえ孤独ですね かっけえ かっけえ "Gott ist tot" 神っぽいな それ 卑怯 神っぽいな それ "my god" 超健康 健康 言い張って くたばっていく感じ ヤケっぽいな それ 畢竟 ヤケっぽいな それ "my god" もう哀愁 哀愁 エピゴーネンのヒール そのタイトル その絵 そのストーリー その音楽 その歌 そのメロディ アレっぽいな それ 比況 アレっぽいな それ その名言 その意見 その批評 そのカリスマ そのギャグ そのセンス 神っぽいな それ 卑怯 ぽいな ぽいな ぽい 憧れちゃうわ とぅ とぅる とぅ とぅ とぅる “風” とぅ とぅる とぅ とぅ とぅる “風” とぅ とぅる とぅ とぅ とぅる “風” ぽいじゃん ぽいじゃん とぅ とぅる とぅ とぅ とぅる “風” とぅ とぅる とぅ とぅ とぅる “風” とぅ とぅる とぅ とぅ とぅる 神っぽいな 愛のネタバレ 「別れ」っぽいな 人生のネタバレ 「死ぬ」っぽいな すべて理解して患った 無邪気に踊っていたかった 人生
miaomaio:什么玩意,听得脑袋疼,下回请你们听儿歌。
上次鲜花已经讲了这题做法,就不在赘述了。
考虑扩展,形式化的,求:
给定
,有 个多项式 ,求其异或卷积。
显然直接暴力有
考虑当
首先我们容易发现,考虑变换后的函数的
考虑 Triple 的解题过程,考虑枚举
考虑到是线性变换,其第
考虑
发现这就是 XOR 变换的系数,于是我们将每个逆变换一下就知道次数了,最后快速幂即可,复杂度
下面代码实现了 的 Triple,可以自行更改 ,注意要改值域
#include<bits/stdc++.h> using namespace std; using llt=long long; using llf=long double; using ull=unsigned long long; #define endl '\n' #ifdef LOCAL FILE *InFile=freopen("in_out/in.in","r",stdin),*OutFile=freopen("in_out/out.out","w",stdout); #else FILE *InFile=stdin,*OutFile=stdout; #endif const int N=1e5+3,MOD=998244353,Inv=(MOD+1)/2,M=17,K=3; int Add(int a,int b){return (a+=b)>=MOD?a-MOD:a;} int Sub(int a,int b){return (a-=b)<0?a+MOD:a;} int n,m,ck,h[1<<K|3][1<<M|3],sm[1<<K|3],c[N][K+3],tim[1<<M|3],cw[K+3],sw[1<<K|3],aas[1<<M|3]; int Fpw(int a,int b){ int ans=1; while(b){ if(b&1) ans=1ll*a*ans%MOD; a=1ll*a*a%MOD,b>>=1; } return ans; } void Fmt(int *f,int l,const function<void(int &,int &)> &F){for(int i=1;i<l;i<<=1) for(int j=0;j<l;++j) if(j&i) F(f[j^i],f[j]);} const auto Xor=[](int &a,int &b){int t=a; a=Add(a,b),b=Sub(t,b);}; const auto IXr=[](int &a,int &b){int t=a; a=1ll*(a+b)*Inv%MOD,b=1ll*(t-b+MOD)*Inv%MOD;}; int main(){ ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr); cin>>n>>m; ck=3; for(int i=0;i<ck;++i) cin>>cw[i]; for(int i=0;i<1<<ck;++i) for(int j=0;j<ck;++j) sw[i]=(i>>j&1)?Sub(sw[i],cw[j]):Add(sw[i],cw[j]); // sw[i] 表示状态是 i 的值。 for(int i=1;i<=n;++i){ for(int j=0;j<ck;++j) cin>>c[i][j]; ++h[0][0]; for(int j=1;j<1<<ck;++j){int low=j&-j,p=__lg(low); ++h[j][sm[j]=sm[j^low]^c[i][p]];} // sm 是异或和,h 维护的是枚举 t 后的多项式。 } for(int i=0;i<1<<ck;++i) Fmt(h[i],1<<m,Xor); // 变换 h for(int i=0;i<1<<m;++i){ for(int j=0;j<1<<ck;++j) tim[j]=h[j][i]; Fmt(tim,1<<ck,IXr); // 复制并做 IFMT aas[i]=1; for(int j=0;j<1<<ck;++j) aas[i]=1ll*aas[i]*Fpw(sw[j],tim[j])%MOD; // 统计 } Fmt(aas,1<<m,IXr); for(int i=0;i<1<<m;++i) cout<<aas[i]<<' '; }
考虑做 OR 卷积,状态设计和推导基本是一样的,就是最后做逆变换是 AND 卷积的逆变换。
下面代码实现了 OR 卷积,没有题,但是和暴力在 值域在模数范围内的随机数据过拍了,应该不会错
#include<bits/stdc++.h> using namespace std; using llt=long long; using llf=long double; using ull=unsigned long long; #define endl '\n' #ifdef LOCAL FILE *InFile=freopen("in_out/in.in","r",stdin),*OutFile=freopen("in_out/out.out","w",stdout); #else FILE *InFile=stdin,*OutFile=stdout; #endif const int N=1003,MOD=998244353,M=10,K=10; int Add(int a,int b){return (a+=b)>=MOD?a-MOD:a;} int Sub(int a,int b){return (a-=b)<0?a+MOD:a;} int n,m,ck,h[1<<K|3][1<<M|3],sm[1<<K|3],c[N][K+3],tim[1<<M|3],cw[K+3],sw[1<<K|3],aas[1<<M|3]; int Fpw(int a,int b){ int ans=1; while(b){ if(b&1) ans=1ll*a*ans%MOD; a=1ll*a*a%MOD,b>>=1; } return ans; } void Fmt(int *f,int l,const function<void(int &,int &)> &F){for(int i=1;i<l;i<<=1) for(int j=0;j<l;++j) if(j&i) F(f[j^i],f[j]);} const function<void(int &,int &)> Or=[](int &a,int &b){b=Add(a,b);},IOr=[](int &a,int &b){b=Sub(b,a);},IAd=[](int &a,int &b){a=Sub(a,b);}; int main(){ ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr); cin>>n>>m>>ck; for(int i=0;i<ck;++i) cin>>cw[i]; for(int i=0;i<1<<ck;++i) for(int j=0;j<ck;++j) if(i>>j&1) sw[i]=Add(sw[i],cw[j]); // sw[i] 表示状态是 i 的值。 for(int i=1;i<=n;++i){ for(int j=0;j<ck;++j) cin>>c[i][j]; ++h[0][0]; for(int j=1;j<1<<ck;++j){int low=j&-j,p=__lg(low); ++h[j][sm[j]=sm[j^low]|c[i][p]];} // sm 是或和,h 维护的是枚举 t 后的多项式。 } for(int i=0;i<1<<ck;++i) Fmt(h[i],1<<m,Or); // 变换 h for(int i=0;i<1<<m;++i){ for(int j=0;j<1<<ck;++j) tim[j]=h[j][i]; Fmt(tim,1<<ck,IAd); // 复制并做 IFMT,做的是 IAnd aas[i]=1; for(int j=0;j<1<<ck;++j) aas[i]=1ll*aas[i]*Fpw(sw[j],tim[j])%MOD; // 统计 } Fmt(aas,1<<m,IOr); for(int i=0;i<1<<m;++i) cout<<aas[i]<<' '; }
AND 类似。
感觉可以上升到子集卷积,有时间在说吧。
P
本文来自博客园,作者:5k_sync_closer,转载请注明原文链接:https://www.cnblogs.com/xrlong/p/18535925
版权声明:本作品采用 「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0) 进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了