4.9 省选模拟赛 生成树求和 变元矩阵树定理 生成函数 iDFT 插值法


有同学在loj上找到了加强版 所以这道题是可以交的。LINK:生成树求和 加强版
对于30分 爆搜 可实际上我爆搜只过了25分 有同学使用按秩合并并茶几的及时剪枝通过了30分。
const int MAXN=45;
int n,m;
struct wy
{
int x,y,z;
}t[MAXN];
int w[MAXN],f[MAXN];ll ans;
inline int getfather(int x){return x==f[x]?x:getfather(f[x]);}
inline int add(int x,int y)
{
int cnt=0;
int p=1;
while(x||y)
{
int w1=x%3;
int w2=y%3;
int cc=(w1+w2)%3;
cnt+=cc*p;
p=p*3;x/=3;y/=3;
}
return cnt;
}
inline void dfs(int x,int v)
{
if(m-x+1<n-v)return;
if(v==n)
{
int cnt=0;
rep(1,n,i)f[i]=i;
rep(1,n-1,i)
{
int xx=getfather(t[w[i]].x);
int yy=getfather(t[w[i]].y);
if(xx==yy)return;
f[xx]=yy;
cnt=add(cnt,t[w[i]].z);
}
ans=(ans+cnt)%mod;
return;
}
w[v]=x;
dfs(x+1,v+1);
dfs(x+1,v);
}
int main()
{
freopen("sum.in","r",stdin);
freopen("sum.out","w",stdout);
get(n);get(m);
rep(1,m,i)
{
int get(x);int get(y);int get(z);
t[i]=(wy){x,y,z};
}
if(m<=35){dfs(1,1);putl(ans);}
return 0;
}
之所以这样做是因为虽然这道题很容易想到矩阵树定理,按位处理 但是依然无法做出来。
矩阵树除了能求方案还可以求边上的权值积的和,即变元矩阵树定理 具体理解可以把边权想象成有边权条重边。
但是对于这道题来说还是不行 求的是生成树边权和的和 把积变和只有是在指数上了。
而且还有三进制的加法 非常的不可做 但是可以按位处理。
把边权变到指数上只能是 生成函数了 列出生成函数 每一条边的权值用生成函数表示。
利用高斯消元解行列式 最后求出的多项式就好了。
而直接使用多项式无法方便的求出行列式 中间由于矩阵树定理还无法取模 所以有多项式乘法除法啥的 所以变的更不可做了。
但是考虑最后的次数 其实并不大最多2n次 可以取2n+1个数带入 然后利用插值求解原多项式。
复杂度\(n^4log\)
为了通过加强版 我们考虑一种比较简单的方式 如果能找到\(x^3=1(mod P)\)
那么我么最后的多项式就只有三项且是正确的了 考虑到复平面单位根。
由于最后有三项 所以 把复平面平分三份的复平面单位根即可。
考虑最后的插值 利用复平面单位根的相加相乘操作可以轻松的插值出来。不需要再次高斯消元或者拉格朗日插值。
非常的巧妙。
const ll MAXN=100010,inv2=(mod+1)>>1,inv3=(mod+1)/3,g3=82062379,maxn=110;
inline ll ksm(ll b,ll p,ll cc){ll cnt=1;while(p){if(p&1)cnt=cnt*b%cc;p=p>>1;b=b*b%cc;}return cnt;}
struct wy
{
ll a,b;
inline wy(ll aa=0,ll bb=0){a=aa;b=bb;}
inline wy operator +(wy w){return wy((a+w.a)%mod,(b+w.b)%mod);}
inline wy operator -(wy w){return wy((a-w.a+mod)%mod,(b-w.b+mod)%mod);}
inline wy operator *(ll y){return wy(a*y%mod,b*y%mod);}
inline wy operator *(wy y){return wy((a*y.a%mod-b*y.b%mod+mod)%mod,(a*y.b+b*y.a)%mod);}
inline wy operator /(ll y)
{
ll inv=ksm(y,mod-2,mod);
return wy(a*inv%mod,b*inv%mod);
}
inline wy operator /(wy y)
{
return wy(a,b)*wy(y.a,mod-y.b)/((y.a*y.a+y.b*y.b)%mod);
}
}a[maxn][maxn],cs[3],inv,w[3],invw[3];
int pow3[maxn],eu[maxn*maxn],ev[maxn*maxn],ec[maxn*maxn];
ll n,m;
inline wy det()
{
wy ret=wy(1,0);
rep(1,n-1,i)
{
ll p=i;
rep(i,n-1,j)if(a[j][i].a||a[j][i].b){p=j;break;}
if(i!=p)
{
rep(1,n-1,k)swap(a[i][k],a[p][k]);
ret=ret*(mod-1);
}
rep(i+1,n-1,j)
{
inv=a[j][i]/a[i][i];
rep(i,n-1,k)a[j][k]=a[j][k]-inv*a[i][k];
}
ret=ret*a[i][i];
}
return ret;
}
inline void idft(wy *p)
{
wy c[3];
c[0]=p[0];c[1]=p[1];c[2]=p[2];
p[0]=c[0]+c[1]+c[2];
p[1]=c[0]+invw[1]*c[1]+c[2]*invw[2];
p[2]=c[0]+invw[2]*c[1]+c[2]*invw[1];
rep(0,2,i)p[i]=p[i]*inv3;
}
inline ll calc(ll p)
{
wy w0,w1,w2,c;
rep(0,2,i)
{
memset(a,0,sizeof(a));
w0=wy(1,0);
w1=w[i];
w2=w[(i+i)%3];
rep(1,m,j)
{
ll k=ec[j]/pow3[p]%3;
c=(k==1?w1:k==2?w2:w0);
a[eu[j]][eu[j]]=a[eu[j]][eu[j]]+c;
a[ev[j]][ev[j]]=a[ev[j]][ev[j]]+c;
a[eu[j]][ev[j]]=a[eu[j]][ev[j]]-c;
a[ev[j]][eu[j]]=a[ev[j]][eu[j]]-c;
}
cs[i]=det();
}
idft(cs);
return (cs[1].a+cs[2].a*2)*pow3[p]%mod;
}
signed main()
{
freopen("1.in","r",stdin);
//freopen("sum.out","w",stdout);
get(n);get(m);ll ans=0;
w[0]=wy(1,0);w[1]=wy(mod-inv2,g3*inv2%mod);
w[2]=wy(mod-inv2,mod-g3*inv2%mod);
invw[0]=w[0]/w[0];
invw[1]=w[0]/w[1];
invw[2]=w[0]/w[2];
rep(1,m,i)get(eu[i]),get(ev[i]),get(ec[i]);
pow3[0]=1;
rep(1,10,i)pow3[i]=pow3[i-1]*3;
rep(0,10,i)ans=(ans+calc(i))%mod;
putl((ans+mod)%mod);return 0;
}
4.9 省选模拟赛 生成树求和 变元矩阵树定理 生成函数 iDFT 插值法的更多相关文章
- P6624-[省选联考2020A卷]作业题【矩阵树定理,欧拉反演】
正题 题目链接:https://www.luogu.com.cn/problem/P6624 题目大意 \(n\)个点的一张图,每条边有权值,一棵生成树的权值是所有边权和乘上边权的\(gcd\),即 ...
- 省选模拟赛 4.26 T1 dp 线段树优化dp
LINK:T1 算是一道中档题 考试的时候脑残了 不仅没写优化 连暴力都打挂了. 容易发现一个性质 那就是同一格子不会被两种以上的颜色染.(颜色就三种. 通过这个性质就可以进行dp了.先按照左端点排序 ...
- 6.6 省选模拟赛 线段 二维数点问题 树套树 CDQ分治
LINK:线段 还是太菜了 没看出这道题真正的模型 我真是一个典型的没脑子选手. 考虑如何查询答案. 每次在一个线段x的状态被更改后 可以发现有影响的是 和x相连那段极长连续1子段. 设这个子段左端点 ...
- 5.21 省选模拟赛 luogu P4207 [NOI2005]月下柠檬树 解析几何 自适应辛普森积分法
LINK:月下柠檬树 之前感觉这道题很鬼畜 实际上 也就想到辛普森积分后就很好做了. 辛普森积分法的式子不再赘述 网上多的是.值得一提的是 这道题利用辛普森积分法的话就是一个解析几何的问题 而并非计算 ...
- 5.20 省选模拟赛 T1 图 启发式合并 线段树合并 染色计数问题
LINK:图 在说这道题之前吐槽一下今天的日子 520 = 1+1+4+514. /cy 这道题今天做的非常失败 一点分都没拿到手 关键是今天的T3 把我整个人给搞崩了. 先考虑 如果得到了这么一张图 ...
- 【洛谷比赛】[LnOI2019]长脖子鹿省选模拟赛 T1 题解
今天是[LnOI2019]长脖子鹿省选模拟赛的时间,小编表示考的不怎么样,改了半天也只会改第一题,那也先呈上题解吧. T1:P5248 [LnOI2019SP]快速多项式变换(FPT) 一看这题就很手 ...
- 省选模拟赛第四轮 B——O(n^4)->O(n^3)->O(n^2)
一 稍微转化一下,就是找所有和原树差距不超过k的不同构树的个数 一个挺trick的想法是: 由于矩阵树定理的行列式的值是把邻接矩阵数值看做边权的图的所有生成树的边权乘积之和 那么如果把不存在于原树中的 ...
- CJOJ 1943 【重庆八中模拟赛】寻找代表元(二分图最大匹配)
CJOJ 1943 [重庆八中模拟赛]寻找代表元(二分图最大匹配) Description 八中一共有n个社团,分别用1到n编号. 八中一共有m个人,分别用1到m编号.每个人可以参加一个或多个社团,也 ...
- loj6271 「长乐集训 2017 Day10」生成树求和 加强版(矩阵树定理,循环卷积)
loj6271 「长乐集训 2017 Day10」生成树求和 加强版(矩阵树定理,循环卷积) loj 题解时间 首先想到先分开三进制下每一位,然后每一位分别求结果为0,1,2的树的个数. 然后考虑矩阵 ...
随机推荐
- VMware实现宿主机和虚拟机处于同一网段
打开虚拟网络编辑器 选择VMnet0桥接模式,在VMnet信息中,选择可以选择的网卡,然后保存. 打开虚拟机设置,在“硬件”选项卡的网络适配器中选择桥接模式即可.
- MySQL Error (Always Continue)
MySQL Error (Always Continue) 其实大部分error在网上都有对应的解决办法,尤其是对Mysql这种使用范围很广的技术.自己就不为每个error单独发布博客了,仅在这里 ...
- java NIO 原理解析之学习笔记
关键抽象 1.Buffer缓冲区 NIO数据传递模型,是一个连续的内存区域.所有数据传递均通过buffer类处理:NIO提供了字符串.整形.字节.堆等多种缓冲区. 2.Channel(通道) NIO把 ...
- C#foreach原理
本文主要记录我在学习C#中foreach遍历原理的心得体会. 对集合中的要素进行遍历是所有编码中经常涉及到的操作,因此大部分编程语言都把此过程写进了语法中,比如C#中的foreach.经常会看到下面的 ...
- postman-7-前置请求脚本
前面讲了,tests初如何校验请求之后返回值是否正确 那前置脚本,就是处理,请求之前接口该如何处理,什么时候会用到呢? 比如:接口字段time,需要填入时间,而且这个是需要当前时间的,: 需要达到自动 ...
- about 蛤蛤
蛤蛤属于蛤蛤门(haha),蛤蛤纲(haha),蛤蛤亚纲(haha),蛤蛤目(haha),蛤蛤总科(haha),蛤蛤科(haha).
- Python GIL(全局解释器锁)
理解并发和并行 并行:多个CPU同时执行多个不同的多任务. 就像两个程序(进程),这两个程序是真的在不同的CPU内同时执行多个任务. 并发:CPU切换处理不同的多任务, 还是有两个程序,但只有一个CP ...
- 数据可视化之DAX篇(三) 认识DAX中的表函数和值函数
https://zhuanlan.zhihu.com/p/64421003 学习 DAX 的过程中,会遇到各种坑,刚开始甚至无法写出一个正确的度量值,总是提示错误.其实很多原因都是不理解 DAX 函数 ...
- three.js 曲线
上几篇说了three.js的曲线,这篇来郭先生来说说three.js曲线,在线案例点击郭先生的博客查看. 1. 了解three.js曲线 之前已经说了一些three.js的几何体,这篇说一说three ...
- Kafka 信息整理
请说明什么是传统的消息传递方法? 传统的消息传递方法包括两种: ·排队:在队列中,一组用户可以从服务器中读取消息,每条消息都发送给其中一个人. ·发布-订阅:在这个模型中,消息被广播给所有的用户. 为 ...