2019.10.22 csp-s模拟测试82 反思总结

算了 我在干什么orz

T2:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=1e5+10,p=1500007,mod=998244353;
int n,len,cnt1=1,cnt2=1,lens;
char s[2*N],c[2*N];
int tree1[2*N][27],tree2[2*N][27];
unsigned long long hash1[2*N],hash2[2*N],ks[2*N];
long long ans;
struct node{
    int m;
    #define m 1500007
    int head[2][m+10],Next[2][2*N],tot[2];
    long long siz[2][2*N];
    unsigned long long ver[2][2*N];
    void ins(unsigned long long has,int opt,long long sum){
        unsigned long long x=has%m;
        for(int i=head[opt][x];i;i=Next[opt][i]){
            if(has==ver[opt][i]){
                siz[opt][i]+=sum;
                return;
            }
        }
        ver[opt][++tot[opt]]=has,siz[opt][tot[opt]]=sum,Next[opt][tot[opt]]=head[opt][x],head[opt][x]=tot[opt];
        return;
    }
    long long get(unsigned long long has,int opt){
        unsigned long long x=has%m;
        for(int i=head[opt][x];i;i=Next[opt][i]){
            if(has==ver[opt][i]){
                return siz[opt][i];
            }
        }
        return 0;
    }
}h;
void insert(){
    int now=1;
    unsigned long long has=0;
    for(int i=1;i<=len;i++){//前缀
        has=has*p+c[i];
        if(!tree1[now][c[i]-‘a‘])tree1[now][c[i]-‘a‘]=++cnt1;
        h.ins(has,0,1);
        now=tree1[now][c[i]-‘a‘];
    }
    now=1,has=0;
    for(int i=len;i>=1;i--){//后缀
        has=has*p+c[i];
        if(!tree2[now][c[i]-‘a‘])tree2[now][c[i]-‘a‘]=++cnt2;
        h.ins(has,1,1);
        now=tree2[now][c[i]-‘a‘];
    }
}
void dfs1(int now,unsigned long long has){
    for(int i=0;i<26;i++){
        if(tree1[now][i]){
            long long val=has*p+i+‘a‘;
            long long sum=h.get(has,0);
            h.ins(val,0,sum);
            dfs1(tree1[now][i],val);
        }
    }
}
void dfs2(int now,unsigned long long has){
    for(int i=0;i<26;i++){
        if(tree2[now][i]){
            long long val=has*p+i+‘a‘;
            long long sum=h.get(has,1);
            h.ins(val,1,sum);
            dfs2(tree2[now][i],val);
        }
    }
}
long long work(int x){
    int l=1,r=x,ans1=0,ans2=0;
    while(l<=r){//后缀
        int mid=(l+r)/2;
        unsigned long long val=hash2[mid]-hash2[x+1]*ks[x-mid+1];
        long long sum=h.get(val,1);
        if(sum){
            ans2=sum;
            r=mid-1;
        }
        else l=mid+1;
    }
    l=x+1,r=lens;
    while(l<=r){//后缀
        int mid=(l+r)/2;
        unsigned long long val=hash1[mid]-hash1[x]*ks[mid-x];
        long long sum=h.get(val,0);
        if(sum){
            ans1=sum;
            l=mid+1;
        }
        else r=mid-1;
    }
    return 1ll*ans1*ans2;
}
int main()
{
    scanf("%s",s+1);
    lens=strlen(s+1);
    ks[0]=1;
    for(int i=1;i<=lens;i++){
        hash1[i]=hash1[i-1]*p+s[i];
        ks[i]=ks[i-1]*p;
    }
    for(int i=lens;i>=1;i--){
        hash2[i]=hash2[i+1]*p+s[i];
    }
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%s",c+1);
        len=strlen(c+1);
        insert();
    }
    dfs1(1,0);
    dfs2(1,0);
    for(int i=1;i<lens;i++){
        ans+=work(i);
    }
    printf("%lld\n",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/chloris/p/11719531.html

时间: 2024-08-30 11:09:56

2019.10.22 csp-s模拟测试82 反思总结的相关文章

2019.10.30 csp-s模拟测试94 反思总结

头一次做图巨的模拟题OWO 自从上一次听图巨讲课然后骗了小礼物以后一直对图巨印象挺好的233 T1: 对于XY取对数=Y*log(x) 对于Y!取对数=log(1*2*3*...*Y)=log1+log2+log3+...+logY 因为数字大小不超过1e5,直接累加最后比较就可以了 #include<iostream> #include<cstdio> #include<cmath> using namespace std; int t,x,y; double a,b

2019/10/17 CSP模拟 总结

T1 补票 Ticket 没什么好说的,不讲了 T2 删数字 Number 很后悔的是其实考场上不仅想出了正解的方程,甚至连优化都想到了,却因为码力不足只打了\(O(n^2)\)暴力,甚至还因为细节挂成了\(40\ pts\) 以后还是应该多写一下码农题 规定一下,下面的\(j\)没有特殊说明,取值范围默认在\(1, i - 1\) 考虑什么情况是合法的,首先最后对答案有贡献的元素组成的序列一定是严格上升的,即\(a_i > a_j\) 然后考虑还有没有别的限制呢 放一个图 看到我们的对答案有贡

2019.10.21 csp-s模拟测试81 反思总结

T1: 把每一行状压,按行DP.设fi,j,k,i表示第几行,j是当前行的1覆盖状态,k是当前行选择按钮的状态.转移的时候枚举j和k,再枚举下一层的按钮选择情况l.如果l和j可以全覆盖当前层则转移合法,根据下一层选择l状态的代价进行转移.预处理一行每一种选法i可以覆盖到的状态di,各行选择按钮状态i对应的代价dpi,以及每一行的初始状态bi.转移时下一层的覆盖情况就是k|dl|bi+1.初始化第一层是所有选法i对应的代价,即f1,d[i]|b[1],i=dp1,i. 整个DP过程的复杂度是O(3

2019.10.26 csp-s模拟测试88 反思总结

今天的主人公是什么? 60.1K!!!! 先扔代码再更新防止我等会儿一上头不打算写完题解 T1: #include<iostream> #include<cstdio> #include<algorithm> using namespace std; const double inf=214748364; int n,k; double a[100010],f[21][100010]; int main() { scanf("%d%d",&n

2019.10.22 校内CSP%你赛

我太难了 先说好没有代码T1 题目大意: 给定一些形如|ax+b|的式子,求最小的x使得它们的和最小. 算法一: 大家知道零点分段法 对于这n个式子我们有n+1个取值范围 使得展开这n个式子得到的新式子不同 而对于每一个形成的式子,因为我们有这个x的取值范围,所以我们可以在O(1)的复杂度求出它的最小值. 而我们从最左边的取值范围开始,对于相邻的两个取值范围我们可以用O(1)的复杂度转移,即我们可以用O(n)遍历所有可能形成的n个式子,每个算一下答案即可. 需要注意的是,对于所有a[i]=0,我

2019.10.22模拟赛

T1 合并集合 有\(n\)个集合,第\(i\)个集合记为\(S_i\),集合按环状排列,即第\(i + 1\)个集合右边是第\(i\)个集合,第\(n\)个集合右边是第\(i\)个集合. 一开始每个集合里只有一个数,每次你可以选择两个相邻的集合\(S,T\),然后合并成\(S \cup T\),之后你可以获得收益\(|S| \times |T|\),其中\(|S|\)表示集合\(S\)的元素个数. 你需要一直进行以上的操作直到只剩一个集合为止,求能获得的最大的收益之和. 断环为链,复制两倍区间

[考试反思]1022csp-s模拟测试82:奇异

这场考试的确颇为奇异. 两道结论题...(其中T1被称为送分题...) 决策不是很对.T1是一个只有一个参数的找规律,明显可以打表. 但是因为搜索不好打所以就没有打... 搜索再难打一个小时应该也可以模拟完了,不说推式子了,找规律肯定是能找到的啊. 然而我T1动都没动... T3跪在了高考组合数学上.... 只有一个参数的题大多是结论题,可以尝试打表找规律. 不要乱弃题! T1: 结论题.大规模推式子,因为只有一个参数,所以打表其实也很好做. 答案是$\frac{n^2-1}{9}$ 推式子先留

2019.10.26 CSP%您赛第三场

\(CSP\)凉心模拟^_^ --题源\(lqx.lhc\)等各位蒟蒻 题目名称 比赛 传递消息 开关灯 源文件名 \(competition.cpp\) \(message.cpp\) \(light.cpp\) 输入文件名 \(competition.in\) \(message.in\) \(light.in\) 输出文件名 \(competition.out\) \(message.out\) \(light.out\) 测试点时限 \(1s\) \(1s\) \(2s\) 内存限制 \

2019.9.28 csp-s模拟测试54 反思总结

咕咕咕的冲动如此强烈x T1x: 看完题目想了想,感觉把gcd不为1的强行放在一组,看作一个连通块,最后考虑连通块之间的组合方式就可以了. 然后维护这个连通块可以写并查集可以连边跑dfs怎么着都行… 然而我在处理数字分解质因数这里T掉了,原因是一个很显然的优化写法我基本没怎么写过.线性筛的时候记录每个数是被哪个质数标记过的,分解一个数的时候直接处理记录下来的质数就可以. #include<iostream> #include<cstdio> #include<cmath>