zoukankan      html  css  js  c++  java
  • 2017 清北济南考前刷题Day 5 morning

    期望得分:100+100+0=200

    实际得分:

     坐标的每一位不是0就是1,所以答案就是

    C(n,k)

    #include<cstdio>
    #include<iostream>
    
    using namespace std;
    
    const int mod=1e9+7;
    
    void read(int &x)
    {
        x=0; char c=getchar();
        while(!isdigit(c)) c=getchar();
        while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
    }
    
    int Pow(int a,int b)
    {
        int res=1;
        for(;b;a=1LL*a*a%mod,b>>=1)
            if(b&1) res=1LL*res*a%mod;
        return res;
    }
    
    int main()
    {
            freopen("cube.in","r",stdin);
        freopen("cube.out","w",stdout);
        int n,k;
        read(n); read(k);
        int ans=1;
        for(int i=1;i<=k;i++) 
            ans=1LL*ans*Pow(i,mod-2)%mod*(n-i+1)%mod;
        cout<<ans;
    }
    View Code

    货物一定是走在最大生成树上

    如果按限重从大到小加边,那么一个联通块只需要有一个仓库

    并查集维护即可

    考场代码写的有点儿乱

    #include<algorithm>
    #include<iostream>
    #include<cstdio>
    
    using namespace std;
    
    #define N 100001
    
    int n,m;
    
    int fa[N];
    bool cal[N];
    
    int ans[N],tmp[N];
    
    bool vis[N];
    
    struct node
    {
        int u,v,lim;
        bool use;
    }e[N];
    
    struct query
    {
        int id,w;
    }a[N];
    
    void read(int &x)
    {
        x=0; char c=getchar();
        while(!isdigit(c)) c=getchar();
        while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
    }
    
    bool cmp(node p,node q) { return p.lim>q.lim; }
    
    bool cmp2(query p,query q) { return p.w>q.w; }
    
    bool cmp3(node p,node q)
    {
        if(p.use!=q.use) return p.use>q.use;
        return p.lim>q.lim;
    }
    
    int find(int i) { return fa[i]==i ? i : fa[i]=find(fa[i]); }
    
    void MST()
    {
        for(int i=1;i<=n;i++) fa[i]=i;
        int tot=0,i=0,u,v;
        while(tot!=n-1 && i<m)
        {
            i++;
            u=find(e[i].u); v=find(e[i].v);
            if(u==v) continue;
            tot++; e[i].use=true;
            fa[u]=v;
        }
    }
    
    int main()
    {
        freopen("warehouse.in","r",stdin);
        freopen("warehouse.out","w",stdout);
        int q;
        read(n); read(m); read(q);
        for(int i=1;i<=m;i++) read(e[i].u),read(e[i].v),read(e[i].lim);
        sort(e+1,e+m+1,cmp);
        for(int i=1;i<=q;i++) read(a[i].w),a[i].id=i;
        sort(a+1,a+q+1,cmp2);
        MST();
        sort(e+1,e+m+1,cmp3);
        for(int i=1;i<=n;i++) fa[i]=i;
        int ne=1,nq=1; int sum=n;
        while(ne<=m)
        {
            if(!e[ne].use) break;
            while(ne<=m && e[ne].lim>=a[nq].w) 
            {
                if(find(e[ne].u)==find(e[ne].v)) 
                {
                    ne++;
                    continue;
                }
                fa[find(e[ne].u)]=find(e[ne].v);
                sum--;
                ne++;
            }
            ans[a[nq].id]=sum;
            nq++;
        }
        for(int i=nq;i<=q;i++) ans[a[i].id]=sum;
        for(int i=1;i<=q;i++) cout<<ans[i]<<'
    ';
    }
    View Code

     

    答案=原词典单词数+前缀后缀拼接单词数

     

    统计前缀和后缀 拼接的单词:

    一个基本错误思路:

    如果有s1个长为l1 的前缀,有s2个长为l2的后缀,那么 他们对长为l1+l2 的单词的贡献为 s1*s2

    错因:有可能会重复计数

     

    例:

    有单词 abc   bcd 

    那么合法单词abcd 会计算3次:

    a+bcd   ab+cd   abc+d

     

    所以对于每个合法的单词,强行规定一个分离位置,来保证一个单词只会被计算一次

    规定的分离位置:

    若单词长为i的前缀是词典中单词的前缀,长为i+1的前缀不是词典中单词的前缀

    那么i就是单词的分离位置

    即这个单词是由前面长为i的前缀 和 i后面的后缀 拼接而成

    在这个不会算重的思路的基础上 

    设f[i][j] 表示 原词典单词中 长度为i的前缀,再加1个字母j就不是前缀的 前缀数量

    g[i][j] 表示 原词典单词中 长为i的后缀,第1个字母是j的 后缀数量

    这两个数组在 正序和倒序 trie树上dfs即可解决

    那么长为 i+k 的 前缀后缀 拼接单词数量 = Σ f[i][j]*g[k][j]   j∈[0,26)

    但思路仍然还有一个bug:

    长为len 的 单词 的所有前缀 都是词典中单词的前缀

    例:

    词典中单词 cool   o

    那么 co 是一个长为2的合法单词

    但是co按上述方法找不到分离位置

    对于这种单词,我们强制规定 最后两个字母之间为分离位置

     

    注意:这种单词还要满足 不是原词典中的单词,后缀非空 两个条件

    所以 设t[i][j] 表示 长为i的前缀,最后一个字母是j 且 不是词典中单词的数量

    注意这里不要把长为1的前缀统计进去

    如果 g[1][j] 那么 长为i的合法单词 就可以累计 t[i][j]

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    
    #define N 10001
    #define L 51
    
    using namespace std;
    
    const int mod=1e9+7;
    
    char s[L];
    
    int ans[101];
    
    int f[L][26],g[L][26],t[L][26];
    
    
    struct TRIE
    {
        int trie[N*L][26],id;
        
        int endd[N*L];
        
        void insert(int len)
        {
            int now=0;
            for(int i=1;i<=len;i++)
            {
                if(!trie[now][s[i]-'a']) trie[now][s[i]-'a']=++id;
                now=trie[now][s[i]-'a'];
            }
            endd[now]++;
        }
        
        void dfs(int x,int dep)
        {
            for(int i=0;i<26;++i)
            {
                if(x && !trie[x][i]) f[dep][i]++;
                if(x && trie[x][i] && !endd[trie[x][i]]) t[dep+1][i]++;
                if(trie[x][i]) dfs(trie[x][i],dep+1); 
            }
        }
        
        void dfs2(int x,int dep)
        {
            for(int i=0;i<26;++i)
                if(trie[x][i]) g[dep+1][i]++,dfs2(trie[x][i],dep+1);
        }
        
    }t1,t2;
    
    int main()
    {
        freopen("word.in","r",stdin);
        freopen("word.out","w",stdout);
        int n,q,len;
        scanf("%d%d",&n,&q);
        for(int i=1;i<=n;i++)
        {
            scanf("%s",s+1);
            len=strlen(s+1);
            t1.insert(len);
            reverse(s+1,s+len+1);
            t2.insert(len);
            ans[len]++;
        }
        t1.dfs(0,0);
        t2.dfs2(0,0);
        for(int i=1;i<=50;++i)
            for(int j=0;j<26;++j)
                if(g[1][j]) ans[i]=(ans[i]+t[i][j])%mod;
        for(int i=1;i<=50;++i)
            for(int k=1;k<=50;++k)
                for(int j=0;j<26;++j)    
                    ans[i+k]=(1LL*ans[i+k]+f[i][j]*g[k][j]%mod)%mod;
        int x;
        while(q--)
        {
            scanf("%d",&x);
            printf("%d
    ",ans[x]);
        }        
    }
    View Code
  • 相关阅读:
    exceljs的使用
    解决ios下的微信打开的页面背景音乐无法自动播放
    js 给定日期转为星期几
    获取地址栏参数
    解决浏览器缓存 或 刷新URL地址
    计算两个日期之间的天数
    获取当前日期的前后N天日期的方法
    将一下 prototype 是什么东西,原型链的理解,什么时候用 prototype
    apply和 call 什么含义,什么区别?什么时候用
    高效Web开发的10个jQuery代码片段
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/7766032.html
Copyright © 2011-2022 走看看