欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 锐评 > CTSC2016 NOIP十合一

CTSC2016 NOIP十合一

2025/2/22 2:24:36 来源:https://blog.csdn.net/asdfghjkl65295/article/details/145668656  浏览:    关键词:CTSC2016 NOIP十合一

题目背景

这是一道 提交答案题

题目描述

在 NOIP2044 的赛场上,小 D 遇到了这样一道题:

给出一个 n 个点的图,其中有 m 条带边权的有向边,有 q 个询问,每个询问形如从 u 号点走到 v 号点,长度为 w 的道路数量有多少?你只需要输出答案对 P 取模的结果即可。

小 D 思考了良久也不会做这道题,悻悻离场后,他从官网上取得了这道题的数据,共有 10 组数据。小 D 怎么也想做出来这道题,于是他开始寻求你的帮助,将 10 组数据的输入给了你。聪明的你一定可以帮小 D 计算出每组数据的输出的!

输入格式

输入文件 noip1.in~noip10.in 已经在下载文件中。

每个输入文件的第一行包括 4 个正整数 n,m,q,P,表示图中点数、边数、询问数目以及模数。点的编号为从 1 到 n 的整数。

接下来 m 行每行描述 m 条带权有向边,其中第 i 行包含 3 个整数 ai​,bi​,ci​,表示第 i 条边的起点为 ai​,终点为 bi​,权值为 ci​。

接下来 q 行描述询问,其中第 k 行包含 3 个整数 uk​,vk​,wk​,表示第 k 个询问需要输出从 uk​ 号店走到 vk​ 号点,长度为 wk​ 的道路数量对 P 取模的结果。

输出格式

输出文件为 noip1.out~noip10.out,分别对应相应的输入文件。

每个输出文件中不超过 q 行,每行包含一个小于 P 的非负整数,表示该测试点前 q 个询问的答案。

输入输出样例

输入 #1复制

3 4 2 10
1 1 2
1 2 2
1 3 1
2 3 3
1 3 5
1 3 3

输出 #1复制

2
1

说明/提示

样例一解释:

对于第一组询问,一共有两条从 1 号点到 3 号点、长度为 5 的路径。假定边的编号从 1 到 4,则这两条路径经过的边为:

第 1 条:2→4

第 2 条:1→1→3。

有关其他样例

在测试数据下载中提供了每个测试点对应的sampleout,分别对应每个测试点第一个询问的正确输出

输入数据下载

下载链接

评分办法

暂无spj,按照 传统题 评分办法进行评测,只有你的答案与标准输出 完全相同 才能得到测试点的分数

提示

本题可能用到的知识:

特征多项式:对于 n×n 的矩阵 A,定义以 λ 为变量的 n 次多项式 f(λ)=det(λI−A),其中 I 是 n 阶单位矩阵,det 是行列式。称 f(λ) 为 A 的特征多项式。

Cayley-Hamilton 定理:对于方阵 A 的特征多项式 f(λ),一定有 f(A)=0。即将矩阵本身作为变量带入特征多项式,结果为零矩阵。

代码:

#include<bits/stdc++.h>
#define REG register
using namespace std;
inline void read(int& x){static char c;while(!isdigit(c=getchar()));x=c^48;while(isdigit(c=getchar()))x=(x*10)+(c^48);
} int n,m,q,p;inline int Pow(int a,int b,int p){int ans(1);while(b){if(b&1) ans=ans*a%p;a=a*a%p,b>>=1;}return ans;
}inline void exgcd(int a,int b,int& x,int& y){b?(exgcd(b,a%b,y,x),y-=a/b*x):(x=1,y=0);}int _InvX,_InvY;
int Inv(int a,int P){_InvY=_InvX=0;exgcd(a,P,_InvX,_InvY);return (_InvX%P+P)%P;
}const int P1=1<<12,P2=Pow(3,8,100005);int _2Mul[10005],_3Mul[10005];
int _2Sig[50005],_3Sig[50005];
int _2Phi[50005],_3Phi[50005];inline void Init(){_2Mul[0]=_3Mul[0]=1;for(REG int i=1;i<P1;++i) _2Mul[i]=_2Mul[i-1]*(i%2?i:1)%P1;for(REG int i=1;i<P2;++i) _3Mul[i]=_3Mul[i-1]*(i%3?i:1)%P2;_2Phi[0]=_3Phi[0]=1;for(REG int i=1;i<=50000;++i)_2Phi[i]=_2Phi[i/2]*_2Mul[i%P1]%P1*Pow(_2Mul[P1-1],i/P1,P1)%P1,_3Phi[i]=_3Phi[i/3]*_3Mul[i%P2]%P2*Pow(_3Mul[P2-1],i/P2,P2)%P2;_2Sig[0]=_3Sig[0]=0;for(REG int i=1;i<=50000;++i) _2Sig[i]=_2Sig[i/2]+i/2,_3Sig[i]=_3Sig[i/3]+i/3;	
}inline int Binom(int n,int m){if(n<m) return 0;int Pw=_2Sig[n]-_2Sig[m]-_2Sig[n-m];int _2Ans,_3Ans;if(Pw>=12) _2Ans=0;else _2Ans=_2Phi[n]*Inv(_2Phi[m],P1)%P1*Inv(_2Phi[n-m],P1)%P1*Pow(2,Pw,P1)%P1;Pw=_3Sig[n]-_3Sig[m]-_3Sig[n-m];if(Pw>=8) _3Ans=0;else _3Ans=_3Phi[n]*Inv(_3Phi[m],P2)%P2*Inv(_3Phi[n-m],P2)%P2*Pow(3,Pw,P2)%P2;return (1ll*_2Ans*P2%p*Inv(P2,P1)%p+1ll*_3Ans*P1%p*Inv(P1,P2)%p)%p;
}inline void Work(){Init();read(n),read(m),read(q),read(p);for(REG int i=1;i<=m;++i){int u,v,w;read(u),read(v),read(w);}while(q--){int u,v,w;read(u),read(v),read(w);if(u==v){printf("%d\n",!w);continue;}if(!(v&1)) --w,--v;u|=1;if(w<0){puts("0");continue;}int Len=(v-u)>>1;printf("%d\n",Binom(Len,w));}
}int main(){Work();}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词