D5上

好慌啊 0分??

T1

感觉是组合数,不知道对不对。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cmath>
#include<ctime>
using namespace std;
const int P=1e9+7;
long long  n,k,ans=1;
int main()
{
    freopen("cube.in","r",stdin);
    freopen("cube.out","w",stdout);
    scanf("%lld%lld",&n,&k);
    int x;
    for(int i=1;i<=n;i++)    scanf("%d",&x);
    for(int i=k+1;i<=n;i++)
    ans=(ans*i)%P;
    for(int i=2;i<=(n-k);i++)
    ans=(ans*i)%P;
    cout<<ans<<'
';
    return 0;
}
first

 完了组合数用错了,应该用逆元的。

思路:
  其实就是说,在n个位置中,找出K个与原来不同的(1或0两种)。

  组合数公式n! / k!(n-k)!  因为数比较大,如果先取模再除 是不对的。

  用乘法逆元,/x %p等价于 *x^P-2 .

  也可以分解质因数,不知道哪根筋抽了,这都没想到。 

T2 

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cmath>
using namespace std;
const int N=1e5+100;
int n,m,q;
struct node{
    int x,y;
    int z;
}a[N],ask[N];
int f[N],tot;
int find(int x)
{
    while(x!=f[x])
        x=f[x]=f[f[x]];
    return x;
}
bool cmp(node u,node v)
{    return u.z>v.z;}
bool fan(node u,node v)
{    return u.y<v.y;}
int main()
{
    freopen("warehouse.in","r",stdin);
    freopen("warehouse.out","w",stdout);
    scanf("%d%d%d",&n,&m,&q);
    for(int i=1;i<=m;i++)    
        scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
    for(int i=1;i<=q;i++)
    scanf("%d",&ask[i].z),ask[i].y=i;
    sort(a+1,a+1+n,cmp);sort(ask+1,ask+1+q,cmp);
    for(int i=1;i<=n;i++)    f[i]=i;
    
    tot=n;int ed=0,i=1,f1,f2;
    for(i=1;i<=q;i++)
    {
        while(a[ed+1].z>=ask[i].z)
        {
            ed++;
            f1=find(a[ed].x);f2=find(a[ed].y);
            if(f1!=f2)
            {
                f[f1]=f2;tot--;
            }
        }
        ask[i].x=tot;
    }
    sort(ask+1,ask+q+1,fan);
    for(int i=1;i<=q;i++)
    printf("%d
",ask[i].x);
    return 0;
}
first

 应该写对了啊,0分。。。

和昨天的题差不多,建一个最大生成树,在合并的过程中更新答案。 

T3

不会去重,甚至计数都不会。

这道题的确不简单,因为一个字符串可能会得到多次,

那我们就就想办法让这个字符串只得到一次,怎么操作那?

维护两个数组a[i][j](表示长度为i的前缀,后面再加j字符就会重复的字符串数量)

      c[i][j](表示以j为开头,长度为i的字符串数量)

    (因为我们只需要考虑,字符串长度,和是否重复)

最后把长度和为L的前缀和后缀字符根据乘法原理组合起来就是答案了。

但是!这样做有漏洞!!

原因是对于本来就是一个单词一部分的字符如coo,它能由co  前缀和 o后缀 组成,但我们却没有判定出co这个前缀。

 a c拼起来的基础是那个合法串从一个位置 开始 前缀变成不合法的了
但是coo这个串,整个串都是合法的
原文地址:https://www.cnblogs.com/CLGYPYJ/p/7764944.html