汕头市队赛 yyl杯1 T1

A SRM 05 - YYL 杯 R1

背景

傻逼题

描述

给一个序列,序列里只有两种元素1和2。现在要从序列里选出一些非空子序列使得子序列里两种元素数量相同。问有多少种方案数?

输入格式

多组数据

第一行一个正整数T,表示数据组数。

每组数据内

第一行 两个个正整数n,表示序列的长度

第二行 n个数字,表示整个序列。

输出格式

一个整数,表示方案数(mod 1e9+7)。

样例输入

1

3

2 2 1

样例输出

2

数据范围与约定

样例解释
在第一个样例中,两个子序列分别为{1,3},{2,3},集合中数字为元素下标。

这道题呢 很容易发现答案和数字的排列顺序无关 我们只需要统计1和2的个数 然后一波组合数就可以推出答案了对吧 23333

但是啊 这题n可以到1e6(但是实测没有....)所以我们不可能用o(n2)的递推预处理组合数 而且空间也不够

这时候我们可以想到预处理阶乘 时间空间都满足而且可以实现o(1)计算组合数的值

但是组合数C(n,m)=n!/m!(n-m)! 而除法是不满足除法过程中取模的

这个时候逆元的派上了用场  a/b==a*power(b,P-2)%P

所以乘法是满足取余性质的 我们就可以o(n)预处理出阶乘取模后的值了

又由费马小定理的 因为p为质数 所以我们可以推出b的逆元

只用一次快速幂就能算出1e6的逆元 然后利用公式

fac(i)=fac(i-1)*i
fac_inv(i-1)=fac_inv(i)*i

tips fac为阶乘fac_inv为阶乘逆元

就可以o(n)预处理逆元了

然后就枚举一波 i—min(cnt1,cnt2) 就可以算出答案了 23333

不过注意每乘一次就要取余一次 不然可能会炸longlong

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
const int mod=1e9+7,M=1000001;
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;
}
LL T,n,cnt1,cnt2,k,ans;
LL w[M],b[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=1000000; w[1]=1;
    for(int i=2;i<=mx;i++) w[i]=w[i-1]*i%mod;
    b[mx]=qmod(w[mx],mod-2,mod); //printf("[%lld]\n",w[mx]);
    for(int i=mx;i>=1;i--) b[i-1]=b[i]*i%mod; //printf("[%d]\n",b[0]);
}
int main()
{
    prepare();
    T=read();
    while(T--){
        n=read();
        cnt1=0; cnt2=0; ans=0;
        for(int i=1;i<=n;i++){
            k=read();
            if(k==1) cnt1++;
            else cnt2++;
        }
        for(int i=1;i<=min(cnt1,cnt2);i++)
            ans=(ans+w[cnt1]*b[i]%mod*b[cnt1-i]%mod*w[cnt2]%mod*b[i]%mod*b[cnt2-i]%mod)%mod;
        printf("%lld\n",ans);
    }
    return 0;
}

时间: 2024-08-24 09:03:03

汕头市队赛 yyl杯1 T1的相关文章

汕头市队赛 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

汕头市队赛 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

汕头市队赛 SRM14 T1 计算几何瞎暴力

计算几何瞎暴力 (easy.pas/c/cpp) 128MB 1s 在平面上,给定起点和终点,有一面墙(看作线段)不能穿过,问从起点走到终点的最短路程. 输入格式 输入一行,包含8个用空格分隔的整数xS,yS,xT,yT,x1,y1,x2,y2,依次表示起点(xS,yS),终点(xT,yT),线段(x1,y1)-(x2,y2). 输出格式 输出一个整数,表示答案四舍五入到整数后的值,保证答案精确值的小数点后一位不是4或5. 样例输入 1 1 2 2 1 2 2 1 样例输出 2 样例解释 走折线

汕头市队赛SRM15

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

汕头市队赛 SRM1X T2 ——扫描线

绵津见-终 SRM 13 背景 "西瓜也是可以种在海上的!"--绵津见 然而种在海上的西瓜最需要防范的,是时不时会涌向瓜田的阵阵海浪. 幸好,身为海神的绵津见可以释放魔法"水平如镜"来阻止海浪拍打西瓜. 然而,当西瓜一个接一个成熟之时,它们就要离开瓜田,飘向遥远的彼岸.绵津见的魔法无法保护离开瓜田的西瓜们,但至少,也得知道西瓜们遭遇了多大的风浪啊. 描述 我们用一个坐标系来描述大海,绵津见的瓜田位于x轴下方,每当有一个西瓜成熟时,它会从x轴上一点出发,沿一条平行y轴

汕头市队赛 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]

汕头市队赛 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)满足琉璃告诉他的信息...你能帮他算出来有多少种吗? 输入格式 两