UOJ272. 【清华集训2016】石家庄的工人阶级队伍比较坚强 [FWT]
思路
很容易想到\(O(3^{3m}\log T)\)的暴力大矩乘,显然过不了。
我们分析一下每次转移的性质。题目给的转移方程是填表法,我们试着改成刷表法看看……
发现好像没啥用。
注意到游戏的规则是1吃0,2吃1,0吃2,也就是在\(x-y=1\pmod 3\)的时候\(x\)吃\(y\)。
我们枚举\(j\),然后再枚举\(i\ominus j\)(这里减法是每一位不退位减法),根据\(i\ominus j\)的状态来更新\(f_i\)。
换句话说,枚举\(j,k\),然后用\(f_j\times b_{cnt1[k],cnt2[k]}\)来更新\(f_{j\oplus k}\)。
发现这就是一个高维循环卷积的形式,用FWT来做。
由于模数的特殊性质,可以发现模数一定和3互质,所以最后是可以得到答案的。
(不太懂网上那么多题解为什么一定要强行分析转移矩阵的性质啊qwq)
代码
我一开始写得太丑了卡不过去,学习了minamoto神仙的代码之后才过。
#include<bits/stdc++.h>
clock_t t=clock();
namespace my_std{
using namespace std;
#define pii pair<int,int>
#define fir first
#define sec second
#define MP make_pair
#define rep(i,x,y) for (int i=(x);i<=(y);i++)
#define drep(i,x,y) for (int i=(x);i>=(y);i--)
#define go(x) for (int i=head[x];i;i=edge[i].nxt)
#define templ template<typename T>
#define sz 550000
typedef long long ll;
typedef double db;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
templ inline T rnd(T l,T r) {return uniform_int_distribution<T>(l,r)(rng);}
templ inline bool chkmax(T &x,T y){return x<y?x=y,1:0;}
templ inline bool chkmin(T &x,T y){return x>y?x=y,1:0;}
templ inline void read(T& t)
{
t=0;char f=0,ch=getchar();double d=0.1;
while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();
while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();
if(ch=='.'){ch=getchar();while(ch<='9'&&ch>='0') t+=d*(ch^48),d*=0.1,ch=getchar();}
t=(f?-t:t);
}
template<typename T,typename... Args>inline void read(T& t,Args&... args){read(t); read(args...);}
char __sr[1<<21],__z[20];int __C=-1,__zz=0;
inline void Ot(){fwrite(__sr,1,__C+1,stdout),__C=-1;}
inline void print(register int x)
{
if(__C>1<<20)Ot();if(x<0)__sr[++__C]='-',x=-x;
while(__z[++__zz]=x%10+48,x/=10);
while(__sr[++__C]=__z[__zz],--__zz);__sr[++__C]='\n';
}
void file()
{
#ifdef NTFOrz
freopen("a.in","r",stdin);
#endif
}
inline void chktime()
{
#ifndef ONLINE_JUDGE
cout<<(clock()-t)/1000.0<<'\n';
#endif
}
// inline ll mul(ll a,ll b){ll d=(ll)(a*(double)b/mod+0.5);ll ret=a*b-d*mod;if (ret<0) ret+=mod;return ret;}
}
using namespace my_std;
int n,m,T,mod;
ll b[15][15];
int add(int x,int y)
{
int cur=1,ret=0;
rep(k,1,m) ret+=(x+y)%3*cur,cur*=3,x/=3,y/=3;
return ret;
}
struct hh{ll x,y;hh(ll X=0,ll Y=0){x=X,y=Y;}}f[sz],w[sz]; // x + y \times \omega
inline ll M1(ll x){return x-((mod-x-1)>>31&mod);}
inline ll M2(ll x){return x+(x>>31&mod);}
hh operator * (hh a,hh b) { return hh(M2(a.x*b.x%mod-a.y*b.y%mod),M2(M1(a.x*b.y%mod+a.y*b.x%mod)-a.y*b.y%mod)); }
hh operator + (hh a,hh b) { return hh(M1(a.x+b.x),M1(a.y+b.y)); }
bool operator < (hh a,hh b){return a.x==b.x?a.y<b.y:a.x<b.x;}
ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x%mod) if (y&1) ret=ret*x%mod;return ret;}
ll Ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x) if (y&1) ret=ret*x;return ret;}
hh kksm(hh x,int y){hh ret=hh(1,0);for (;y;y>>=1,x=x*x) if (y&1) ret=ret*x;return ret;}
void exgcd(ll a,ll b,ll &x,ll &y)
{
if (a==1&&!b) return (void)(x=1,y=0);
exgcd(b,a%b,y,x);y=M2(y-a/b*x%mod);
}
ll inv(ll x){ll a,b;exgcd(x,mod,a,b);return (a+mod)%mod;}
hh calc1(hh a){return hh(M2(-a.y),M2(a.x-a.y));}
hh calc2(hh a){return hh(M2(a.y-a.x),M2(-a.x));}
void FWT(hh *a,int type)
{
for (int len=1,i=0;i<m;i++,len*=3) for (int j=0;j<n;j+=len*3) rep(k,0,len-1)
{
hh x=a[j+k],y=a[j+k+len],z=a[j+k+len*2],Y1=calc1(y),Y2=calc2(y),Z1=calc1(z),Z2=calc2(z);
if (type==-1) swap(Y1,Y2),swap(Z1,Z2);
a[j+k]=x+y+z;
a[j+k+len]=x+Y1+Z2;
a[j+k+len+len]=x+Y2+Z1;
}
}
int main()
{
file();
read(m,T,mod);n=Ksm(3,m);
if (mod==1) { rep(i,0,n-1) puts("0"); return 0; }
rep(i,0,n-1) read(f[i].x);
rep(i,1,m+1) rep(j,1,m+2-i) read(b[i-1][j-1]);
rep(i,0,n-1)
{
int x=i,y=i,c1=0,c2=0;
rep(k,1,m) c1+=(x%3==1),x/=3;
rep(k,1,m) c2+=(y%3==2),y/=3;
w[i].x=b[c1][c2];
}
FWT(w,1);FWT(f,1);
map<hh,hh>M;
rep(i,0,n-1) w[i]=(M.count(w[i])?M[w[i]]:M[w[i]]=kksm(w[i],T))*f[i];
FWT(w,-1);
ll I=inv(n);
rep(i,0,n-1) printf("%lld\n",w[i].x*I%mod);
return 0;
}
UOJ272. 【清华集训2016】石家庄的工人阶级队伍比较坚强 [FWT]的更多相关文章
- UOJ272 [清华集训2016] 石家庄的工人阶级队伍比较坚强 【分治乘法】
题目分析: 首先不难注意到式子就是异或卷积,所以考虑用分治乘法推出优化方法.我们把一个整体$f$拆成$f-,f\pm,f+$,然后另一个拆成$g-,g\pm,g+$.这样做的好处是能更清楚的分析问题. ...
- [清华集训2016]石家庄的工人阶级队伍比较坚强——三进制FWT
题目链接: [清华集训2016]石家庄的工人阶级队伍比较坚强 题目大意:有$n=3^m$个人玩石头剪刀布,共$t$轮游戏,每轮每个人要和包括自己的所有人各进行$m$次石头剪刀布.每个人在$m$轮中的决 ...
- uoj#272. 【清华集训2016】石家庄的工人阶级队伍比较坚强
http://uoj.ac/problem/272 这题的式子形式是异或卷积的三进制推广,因此可以设计一个类似fwt的变换,这里需要一个三次单位根$w$,满足$w^3\%p==1$且$(1+w+w^2 ...
- [uoj272]石家庄的工人阶级队伍比较坚强
假设$x,y\in \{0,1,2\}$,则$x$能赢$y$(根据题中定义)当且仅当$x-y\equiv 1(mod\ 3)$ 定义$\ominus$为两数3进制下不退位的减法,$S_{x}$表示$x ...
- UOJ #274. 【清华集训2016】温暖会指引我们前行 [lct]
#274. [清华集训2016]温暖会指引我们前行 题意比较巧妙 裸lct维护最大生成树 #include <iostream> #include <cstdio> #incl ...
- UOJ_274_[清华集训2016]温暖会指引我们前行_LCT
UOJ_274_[清华集训2016]温暖会指引我们前行_LCT 任务描述:http://uoj.ac/problem/274 本题中的字典序不同在于空串的字典序最大. 并且题中要求排序后字典序最大. ...
- UOJ 275. 【清华集训2016】组合数问题
UOJ 275. [清华集训2016]组合数问题 组合数 $C_n^m $表示的是从 \(n\) 个物品中选出 \(m\) 个物品的方案数.举个例子,从$ (1,2,3)(1,2,3)$ 三个物品中选 ...
- UOJ #269. 【清华集训2016】如何优雅地求和
UOJ #269. [清华集训2016]如何优雅地求和 题目链接 给定一个\(m\)次多项式\(f(x)\)的\(m+1\)个点值:\(f(0)\)到\(f(m)\). 然后求: \[ Q(f,n,x ...
- 【UOJ274】【清华集训2016】温暖会指引我们前行 LCT
[UOJ274][清华集训2016]温暖会指引我们前行 任务描述 虽然小R住的宿舍楼早已来了暖气,但是由于某些原因,宿舍楼中的某些窗户仍然开着(例如厕所的窗户),这就使得宿舍楼中有一些路上的温度还是很 ...
随机推荐
- Spring Cloud Alibaba学习笔记(16) - Spring Cloud Gateway 内置的路由谓词工厂
Spring Cloud Gateway路由配置的两种形式 Spring Cloud Gateway的路由配置有两种形式,分别是路由到指定的URL以及路由到指定的微服务,在上文博客的示例中我们就已经使 ...
- Java调用Http/Https接口(1)--编写服务端
Http接口输入的数据一般是键值对或json数据,返回的一般是json数据.本系列文章主要介绍Java调用Http接口的各种方法,本文主要介绍服务端的编写,方便后续文章里的客户端的调用.文中所使用到的 ...
- 【转载】Asp.net网站安全:去除网站根目录下的备份文件防止代码泄露
很多网站运维人员在更新网站版本的时候,喜欢直接在网站目录文件夹中直接压缩原来的网站文件,如果这个备份压缩文件没有移动出去,这样是非常不安全的,有些网站攻击者可能会尝试访问你网站下有没有对应名字的压缩备 ...
- 页面、 ajax 、mock
页面1: //html <form action = "" method="post" name="loginForm"> & ...
- STM32F10x芯片类型 STM32F10X_LD STM32F10X_MD STM32F10X_HD STM32F10X_XL STM32F10X_CL
stm32f10x.h 固件库stm32f10x.h中有如下解释 #if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) & ...
- Dubbo 高级特性实践-泛化调用
引言 当后端Java服务用Dubbo协议作为RPC方案的基础,但部分消费方是前端Restful的PHP服务,不能直接调用,于是在中间架设了Router服务提供统一的基于HTTP的后端调用入口. 而Ro ...
- SQL SERVER-解析Extendevent文件数据
--解析xel数据 select SWITCHOFFSET(n.value('@timestamp','Datetime'),'+08:00') as EventTime, n.value('(dat ...
- 华为云PaaS首席科学家:Cloud Native +AI,企业数字化转型的最佳拍档
近日,在2019华为全球分析师大会期间,华为云PaaS首席科学家熊英博士在+智能,见未来(华为云&大数据)的分论坛上,从云计算行业发展谈起,深入云原生发展趋势,对华为云智能应用平台做了深度解读 ...
- 使用AutoIt实现文件上传
在网页上上传文件的时候,Selenium无法直接操作如Flash.JavaScript 或Ajax 等技术所实现的上传功能,这时候我们需要借用一个叫做AutoIt的软件来帮助我们事先自动化的上传操作. ...
- 《CoderXiaoban》第八次团队作业:Alpha冲刺4
项目 内容 这个作业属于哪个课程 任课教师博客主页链接 这个作业的要求在哪里 实验十二 团队作业8:软件测试与ALPHA冲刺 团队名称 Coderxiaoban团队 作业学习目标 (1)掌握软件测试基 ...