题目

我们的神仙教练在考试里放了这道题,当时我非常惊讶啊

背包是\(O(n^3)\)的吧明明是带根号的好吧,那既然要优化的话

NTT!什么时候我们教练会在考试里放多项式了

模数\(1e9+7\)?

任意模数不存在的,我们开int128找一个大一点的\(NTT\)模数就可以了

还是说一下\(NTT\)的做法吧,发现我们要求长度大于\(Y\)的路径可能不太好求,于是我们正难则反一下,我们求出有多少种拼法可以使得路径长度小于\(Y\)就可以了

每一棵树里只能出一条路径,于是我们可以把一棵树的路径信息搞成一个多项式,系数代表这种长度的路径出现了多少次

我们把每棵树的多项式卷起来就是最后的答案了

并不保证随时能通过而且我们不怎么能看懂的代码

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define re register
#define _LL __int128
#define LL long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#pragma GCC optimize(3)
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("Ofast,no-stack-protector")
char BB[1<<18],*S=BB,*T=BB;
const int maxn=1505;
inline int read() {
char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
struct E{int v,nxt,w;}e[maxn<<1];
const LL mod=4222124650659841;
const LL P=1e9+7;
_LL G[2],t,og;
_LL mi[2][16];
int head[maxn],sum[maxn];
int n,m,X,Y,tot,num;
int rev[10000],len,fa[maxn],vis[maxn],pre[maxn];
int tax[1501][2501];LL tp[maxn];
_LL A[9000],B[9000];
LL tmp=1,k=0;
inline void add(int x,int y,int w) {
e[++num].v=y;e[num].nxt=head[x];
head[x]=num;e[num].w=w;
}
inline _LL ksm(_LL a,LL b) {
_LL S=1;
while(b) {if(b&1ll) S=S*a%mod;b>>=1ll;a=a*a%mod;}
return S;
}
void exgcd(LL a,LL b,LL &x,LL &y) {
if(!b) {x=1,y=0;return;}
exgcd(b,a%b,y,x);
y-=a/b*x;
}
inline LL getInv(LL a) {
LL x,y;exgcd(a,P,x,y);
return (x%P+P)%P;
}
void write(LL x){
if(x==0){putchar(48);return;}
int len=0,dg[25];
while(x>0){dg[++len]=x%10ll;x/=10ll;}
for(int i=len;i>=1;i--)putchar(dg[i]+48);
}
inline void NTT(_LL *f,int o) {
for(re int i=0;i<len;i++) if(i<rev[i]) std::swap(f[i],f[rev[i]]);
for(re int i=2,k=0;i<=len;i<<=1,k++) {
int ln=i>>1;
LL og1;
if(!mi[o][k]) {mi[o][k]=og1=ksm(G[o],(mod-1)/i);}
else og1=mi[o][k];
for(re int l=0;l<len;l+=i) {
og=1;
for(re int x=l;x<ln+l;++x) {
t=(f[ln+x]*og)%mod;
f[ln+x]=(f[x]-t+mod)%mod;
f[x]=(f[x]+t)%mod;
og=(og*og1)%mod;
}
}
}
if(!o) return;
_LL inv=ksm(len,mod-2);
for(re int i=0;i<len;i++) f[i]=(f[i]*inv)%mod;
}
void dfs(int x,int Fa) {
++k;
fa[x]=Fa;vis[x]=1;
for(re int i=head[x];i;i=e[i].nxt) {
if(vis[e[i].v]) continue;
dfs(e[i].v,Fa);
}
}
void Dfs(int x,int fa,int p) {
for(re int i=head[x];i;i=e[i].nxt) {
if(e[i].v==fa) continue;
pre[e[i].v]=pre[x]+e[i].w;
if(pre[e[i].v]<Y) tax[p][pre[e[i].v]]++;
else tp[p]+=pre[e[i].v];
Dfs(e[i].v,x,p);
}
}
inline void mul() {
NTT(A,0),NTT(B,0);
for(re int i=0;i<len;i++) A[i]=(A[i]*B[i])%mod;
NTT(A,1);
for(re int i=0;i<Y;i++) A[i]%=P;
//中间取模的简易版任意模数NTT
for(re int i=Y;i<len;i++) A[i]=0;
}
int main() {
G[0]=19ll,G[1]=ksm(19ll,mod-2);
n=read(),m=read(),X=read(),Y=read();
for(re int x,y,z,i=1;i<=m;i++)
x=read(),y=read(),z=read(),add(x,y,z),add(y,x,z);
LL cnt=0,H=0,T=0;
for(re int i=1;i<=n;i++)
if(!vis[i]) {
k=0;++tot,dfs(i,tot);
k=k*(k-1ll)/2ll;sum[tot]=k;
tmp=(tmp*k)%P;
}
Y-=tot*X;
for(re int i=1;i<=n;i++) pre[i]=0,Dfs(i,0,fa[i]);
A[0]=1;len=1;while(len<Y+Y) len<<=1;
for(re int i=0;i<len;i++) rev[i]=rev[i>>1]>>1|((i&1)?len>>1:0);
for(re int i=1;i<=tot;i++) {
for(re int j=0;j<len;j++) B[j]=0;
LL inv=tmp*getInv(sum[i])%P;
for(re int j=0;j<Y;j++) {
B[j]=(tax[i][j]/2);
H+=(inv*(LL)j%P*(LL)(tax[i][j]/2ll)%P);
H%=P;
}
H+=inv*(tp[i]/2ll)%P;H%=P;
mul();
}
//H是所有环的长度和,tmp是所有环的方案数
//cnt是不满足条件的环的方案数,T是不满足条件的环的长度和
for(re int i=1;i<Y;i++)
cnt=(cnt+A[i])%P,T=(T+A[i]*(LL)i%P)%P;
H=(H-T+P)%P;
tmp=(tmp-cnt+P)%P;
H+=tmp*(LL)tot%P*(LL)X%P;H%=P;
if(tot==1) {write(H);return 0;}
if(tot==2) write(H*2ll%P);
else {
LL pw=2,now=4;tot-=2;
for(re int i=1;i<=tot;i++)
pw=(pw*now)%P,now=(now+2ll)%P;
write(H*pw%P);
}
return 0;
}

[USACO19FEB]Moorio Kart的更多相关文章

  1. [USACO19FEB]Moorio Kart(DP)

    Luogu5243 题解 即O(N^2)暴力统计出每个森林的路径,从ctgn个集合中各选出一个数,使得长度>=Y的方案数. 用背包统计.具体实现: \(dp[i+j][0]\leftarrow ...

  2. DP小小结

    入门题 : [Luogu1441]砝码称重 , [NOIP2015]子串 [AHOI2009]中国象棋 , 详见代码 [HNOI2007]梦幻岛宝珠 , 详见代码 [NOIP2012]开车旅行 , 没 ...

  3. 解题报告:luogu P5543 [USACO19FEB]The Great Revegetation S

    题目链接:P5543 [USACO19FEB]The Great Revegetation S 好坑啊,都身败名裂了. 思路一: 考虑染色法,跑一遍搜所就好了,不给代码了. 思路二: 考虑并查集,我想 ...

  4. [USACO19FEB]Mowing Mischief

    题目大意: 给定平面上的一些点,求这些点的一个\(LIS\),并且还需要满足下列式子最小: \[ \sum_{i=1}^{n-1}(a[i+1].x-a[i].x)*(a[i+1].y-a[i].y) ...

  5. P5242 [USACO19FEB]Cow Dating

    题目链接 题意分析 首先我们可以得出计算公式 \[s_i=\prod_{k=1}^i(1-p_k)\] \[f_i=\sum_{k=1}^i\frac{p_k}{1-p_k}\] 那么 \[ans(i ...

  6. [USACO19FEB]Cow Dating

    Luogu5242 通过观察数据,我们可以发现,右端点的取值是单调递增的.于是,我们可以极限一波,用一个双指针法,类似于队列. 右端点的取值满足以下公式: (1-p1)(1-p2)..(1-pn) * ...

  7. P5541 [USACO19FEB]Sleepy Cow Herding

    ri,被黄题虐. 思路:贪心?? 提交:2次 错因:没有特判 题解: 先排序. 最小代价:固定区间长度为\(n\),我们扫一遍数组看区间最多包含几个数,设为 \(mx\) ,答案就是\(n-mx+1\ ...

  8. [USACO19FEB]Cow Dating——找规律

    原题戳这里 题解 显然原题等价于让我们求这个式子\(\prod\limits_{i=l}^{r}(1-p_i)\sum\limits_{i=l}^{r}\frac{p_i}{1-p_i}\)的最大值是 ...

  9. [USACO19FEB]Painting the Barn G

    题意 \(n\)个矩阵\((0\le x_1,y_1,x_2,y_2\le 200)\),可交,可以再放最多两个矩阵(这两个矩阵彼此不交),使得恰好被覆盖\(k\)次的位置最大.\(n,k\le 10 ...

随机推荐

  1. GDC NEC单机自动化设置

    GDC NEC 单机自动化设置 进入播放列表   进入设置,进入登陆,请选择维修员登陆,输入密码257910   选择“一般选项”中的“自动化” 在进入的新菜单中选择“设备”,添加一个新的名称,默认的 ...

  2. java工程师_基础_阶段一_HTML笔记篇

    一.了解HTML语言 html:超文本标记语言. 二.HTML整体结构<html> <head> </head> <body> </body> ...

  3. BZOJ4364: [IOI2014]wall砖墙(线段树)

    题意 题目链接 Sol 一个显然的思路是维护最大最小值以及最大最小值的覆盖标记. https://paste.ubuntu.com/p/WXpBvzF6Y2/ 但实际上因为这题只需要输出最后的操作序列 ...

  4. freecodecamp 基础算法题笔记

    数组与字符串的转化 字符串转化成数组 reverse方法翻转数组顺序 数组转化成字符串. function reverseString(str) { a= str.split("" ...

  5. css中的线及vertical-align

    行内元素格式化顺序: 相关概念:  leading(行间距):指填充在两行文字间的铅条,等于line-height 和 font-size之差,其中一半leading加到文字上方,另一半leading ...

  6. 使用display:none和visibility:hidden隐藏的区别

    今天做毕设时遇到了一个小问题,我做了一个tab导航栏,点击一个tab页其它tab页隐藏,这时候第一想法是使用display:none来控制显示隐藏,写了之后发现使用display会有一个问题,就是第二 ...

  7. TCP报文发送工具

    该工具用于向Socket服务端发送XML报文,软件功能界面如下图所示: 配置好IP和端口后,单击"载入报文文件"按钮,在文件选择对话框中选择报文文件,如图: 报文文件打开后,可在右 ...

  8. mybatis 在存储Integer、bigdecimal等java数据类型时,将0存成null

    我们的项目中,有关于金额的计算,所以,一般在java环境中我们使用bigdecimal来做运算和存储金额信息.数据库sqlServer2008用的float类型 问题是,当我将金额赋值成0时,很意外的 ...

  9. 浅谈 java 反射机制

    一:Java反射概念 Java反射是Java被视为动态(或准动态)语言的一个关键性质.这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其mod ...

  10. leetCode题解寻找最短字符路径

    1.题目描述 2.分析 最简单的方案,对每一个字符,向两边寻找. 3.代码 vector<int> shortestToChar(string S, char C) { vector< ...