汕头市队赛 SRM10 T3 数学上来先打表

数学上来先打表 SRM 10

描述

给出 n个点(不同点之间有区别),求出满足下列条件的连边(双向边)方案:
1.每条边连接两个不同的点,每两个点之间至多有一条边
2.不存在三个点a,b,c使三个点间两两可以互相到达且两两之间最短距离相等
3.边的长度均为1

输入格式

一行,一个整数n

输出格式

一行,一个整数,表示方案数对1004535809取模的结果。

样例输入

3

样例输出

7

数据范围与约定

对于8组数据,1<=n<=9
对于余下8组数据,10<=n<=2000

样例解释

三个点之间没有边,有1种方案
三个点之间有一条边,有3种方案
三个点之间有两条边,有3种方案

—————————————————————

这道题观察可得这n个数组成的不是环就是链

是环还必须大于3且不能是3的倍数

我们任然可以先预处理出各个阶乘的逆元

T是2关于mod的逆元 这个根据费马小定理可以算出来

f【i】表示大小为i的联通块的个数

如果是链 方案数是 i!/2 这个时候T作为2的逆元就显示出作用辣

至于为什么是i!/2 因为各个点不同我们可以看作是排列而一个排列对应一个方案,一个方案被算两次

如果是环 就是(i-1 )!/2 因为是环我们可以钦定一个数作为起点 剩下i-1个数来排列

当然只有1不符合上述推断 所以要单独考虑

这样处理完之后我们就可以来算答案ans辣

ans【k】=sigma(1-k) f【i】*g【k-i】*C(i-1,j-1);

也就是我们选i个数作为联通快其余随意的总和

至于为什么是C(i-1,j-1)

因为如果固定一个点统计,g就可以每个图只算一次

这样才能保证每个合法方案中只有一个连通块被算到,且只算了一次

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
const int M=2007,mod=1004535809;
LL read(){
    LL ans=0,f=1,c=getchar();
    while(c<‘0‘||c>‘9‘){if(c==‘-‘) f=-1; c=getchar();}
    while(c>=‘0‘&&c<=‘9‘){ans=ans*10+(c-‘0‘); c=getchar();}
    return ans*f;
}
int n;
LL T,w[M],b[M],f[M],ans[M];
LL qmod(LL a,LL b,LL c){
    LL ans=1;
    while(b){
        if(b&1) ans=ans*a%c;
        b=b/2;
        a=a*a%c;
    }
    return ans;
}
void prepare(){
    int mx=2000; w[0]=1;
    for(int i=1;i<=mx;i++) w[i]=w[i-1]*i%mod;
    b[mx]=qmod(w[mx],mod-2,mod);
    for(int i=mx;i>=1;i--) b[i-1]=b[i]*i%mod;
    T=qmod(2,mod-2,mod);
}
LL C(int n,int m){return w[n]*b[m]%mod*b[n-m]%mod;}
int main()
{
    n=read();
    prepare();
    f[1]=1;
    for(int i=2;i<=n;i++){
        f[i]=w[i]*T%mod;
        if(i>3&&i%3) f[i]=(f[i]+w[i-1]*T)%mod;
    }
    ans[0]=1;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=i;j++){
            ans[i]=(ans[i]+f[j]*ans[i-j]%mod*C(i-1,j-1)%mod)%mod;
        }
    }
    printf("%lld\n",ans[n]);
    return 0;
}

时间: 2024-10-14 08:53:50

汕头市队赛 SRM10 T3 数学上来先打表的相关文章

汕头市队赛 SRM13 T3

这道题可以贪心 维护一个答案队列 枚举位置 每次将比当前位置大的队尾全部替代掉 记录删了多少了就好了 #include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<string> #define LL long long using namespace std; const int M=1e7+7; int n,k,cnt; char s[M]

汕头市队赛SRM14 T3覆盖

我们可以考虑两种情况 区间之间不相重叠 和 重叠 f[i][j]表示以当前最后一个区间以 i 结尾 并且选了 j 个区间 不相重叠的话 只要选 1-i-w 的max再加上 包含i在内的前四个数的和 相交的话 考虑因为可选的区间长度是固定的 所以我们可以考虑单调队列优化 sum维护的是前缀和 f[i][j]=f[k][j-1]+sum[i]-sum[k] 这样因为sum[i]是固定的 所以我们队列里维护的是f[k][j-1]-sum[k]就好辣 #include<cstdio> #include

汕头市队赛 SRM10 T1模拟只会猜题意

模拟只会猜题意 SRM 10 描述 有一本n个单词的词典,求按下列方法能造出的不相同的词汇数目.  1.词典中的单词是一个词. 2.能分为两部分的,其中前一部分是一个词典词或者其非空前缀,后一部分是一个词典词或者其非空后缀的词. 输入格式 第一行一个整数n,接下来n行每行一个字符串,表示单词 输出格式 一个整数,答案 样例输入 3 a ab bc 样例输出 20 数据范围与约定 对10%的数据,n=1 对另外40%的数据,1<=n<=10,单词只含字符'a' 对所有的数据,1<=n<

汕头市队赛 SRM10 T1 贪心只能过样例

贪心只能过样例 SRM 10 描述 给出n个数a[i](1<=a[i]<=n),问最多能把这些数分成几组,使得每个数a[i]所在的组至少有a[i]个数 输入格式 第一行一个整数n,接下来n行每行一个整数分别是a[1],a[2],...,a[n] 输出格式 一行,输出答案,一个整数 样例输入 5 2 1 2 2 3 样例输出 2 数据范围与约定 数据有梯度,分布如下: 0<n<=20 7组数据 20<n<=5000 15组数据 5000<n<=1000000

汕头市队赛 C KMP codeforces B. Image Preview

汕头市队赛题目传送门 codeforces题目传送门 这道题我的做法是 尝试先往左走然后往右走 或者先往右走然后往左走 然后注意一下枚举顺序就okay啦 #include<cstdio> #include<cstring> #include<algorithm> #define LL long long using namespace std; const int M=1e6+7; LL read(){ LL ans=0,f=1,c=getchar(); while(c

汕头市队赛SRM15

T1--czl SRM 15 众所周知,czl家养了一只可♂爱的***(已屏蔽),那只东西很贪吃,所以czl家很多零食仓库,然而这些仓库里有很多老鼠. 为了心爱的***,czl决定点燃纯艾条,用烟熏老鼠. 共有N个仓库,编号1-N. 假设陵陵在第i个仓库点燃艾条,烟雾就会充满该仓库,并向左右扩散Ai 的距离,接着所有|i-j|<=Ai 的仓库 j 的老鼠被消灭. 陵陵是个爱护环境的人,他想知道最少需要多少支艾条,才可以消灭所有老鼠. [输入格式] 第一行:一个正整数,代表 N. 第二行:N 个非

汕头市队赛 SRM16

T3 C-2 SRM 16 描述 给一个数列,给出两种数字, 询问在多少个非空区间中这两种数字出现次数相同. 输入格式 第一行:一个数字n,q,n表示数列长度,q表示q组询问 第二行n个数字表示数列A 接下来q行每行2个数字表示询问 输出格式 输出q行分别对应每个问题的答案 样例输入 2 1 1 2 1 2 样例输出 1 数据范围与约定 n <= 5000,q <= 10000 其他数字在int范围内 样例解释 只有区间[1,2]符合 -------------------------- 因为

汕头市队赛 SRM 09 A 撕书

A 撕书I-3 SRM 09 背景&&描述 琉璃在撕书.     书总共有n页,都悬浮在数轴上,第i页的位置为,上面写着一个数字.     琉璃从右往左撕书.假如看到了第i页,就把在第i页左边,且与之距离<=的书都撕掉.(第i页本身不撕)     夜子为了尽量地保全魔法书,决定偷偷在琉璃开始撕之前,增加一页.增加的这一页必须在所有书页的右边,数字随意.     夜子想知道,最少会有多少页书被撕毁. 输入格式 第一行一个整数n,表示书页数. 接下来n行,第i行的俩整数分别为和. 输出格

汕头市队赛 SRM 09 B 撕书

B 撕书II-3 SRM 09 背景&&描述 琉璃手头有一黑一白两本魔法书,一本是<缟玛瑙的不在证明>,另一本是<白色相簿1.5>     传说同时打开这两本书会有奇怪的事情发生.     琉璃打开一看,果然非常奇怪:两本书上都各自写着一个正整数(可能他买到盗版了),分别是a和b.     试图撕书的汀想借过来看看,但琉璃只告诉了他这俩数加起来的值x和异或起来的值y.     汀发现有很多种(a,b)满足琉璃告诉他的信息...你能帮他算出来有多少种吗? 输入格式 两