zoukankan      html  css  js  c++  java
  • ZJNU 2035

    给定一段字符串S

    给定Q次询问,每次询问存在多少个长度为D的子串(char型子序列),以字母AB结尾

    |S|最大为2000,Q最大为50w

    显而易见,我们只考虑结尾为AB字符的子串

    所以可以根据A的位置,求出A位置前有多少字符,用组合数可以求出能够得到多少组合

    即假设某个字符A的位置为p,则A前字符组合个数为 C[D-2][p-1] ,即从p-1个字符中取D-2个字符的取法数

    然后考虑B字符,只需要后缀处理一下到某个位置时某个字符出现次数即可,采用结构体或者二维数组均可

    对于A的位置,采用vector或是26个数组+26个计数变量记录每种字符出现的所有位置下标,再从中循环一遍即可

    最后答案为Σ (p∈A) C[D-2][p-1] * count { B -> p+1~Len } (%1e9+7)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll mod=1e9+7;
    struct node{
        int v[26];
    }ar[2050];
    vector<int> vec[26];
    char s[2050];
    int C[2050][2050];
    void solve(){
        int Q,D,i,cnt,pos;
        char ch[5];
        cin>>Q;
        while(Q--){
            ll ans=0;
            cin>>D>>ch;
            cnt=vec[ch[0]-'a'].size();
            for(i=0;i<cnt;i++){
                pos=vec[ch[0]-'a'][i];
                ans=(ans+1LL*ar[pos+1].v[ch[1]-'a']*C[D-2][pos-1])%mod;
            }
            cout<<ans<<'
    ';
        }
    }
    int main(){
        ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
        int i,j,len;
        C[0][0]=C[0][1]=C[1][1]=1;
        for(i=2;i<=2000;i++){
            C[0][i]=C[i][i]=1;
            for(j=1;j<i;j++)
                C[j][i]=(C[j][i-1]+C[j-1][i-1])%mod;
        }//杨辉三角求组合数
        cin>>(s+1);
        len=strlen(s+1);
        for(i=0;i<26;i++)
            ar[len].v[i]=0;
        ar[len].v[s[len]-'a']=1;
        vec[s[len]-'a'].push_back(len);
        for(i=len-1;i;i--){
            ar[i]=ar[i+1];
            ar[i].v[s[i]-'a']++;//后缀预处理
            vec[s[i]-'a'].push_back(i);//位置储存
        }
        solve();
        
        return 0;
    }
  • 相关阅读:
    程序员的自我修养(序)-量子
    我的IT生活-量子
    量子地图
    再出发
    新的一年快开始了,学点新东西吧,从React开始(一)
    ECMAScript 6 Features 中文版
    必须清零
    彩印网的第一阶段即将收官
    终于感觉掌握了一门重要的技术
    程序员的命运之轮
  • 原文地址:https://www.cnblogs.com/stelayuri/p/12420861.html
Copyright © 2011-2022 走看看