CF 294 div2 D. A and B and Interesting Substrings (hash)

来源:互联网 发布:天刀客户端优化 编辑:程序博客网 时间:2024/06/03 11:27

题目:http://codeforces.com/contest/519/problem/D

题意:在字符串里面找出有多少子串除首尾字符,其权值的和为0,且首尾字符相同。

分析:将字符和前缀和插入hash表,然后查询字符前缀和,注意去重。

代码:

#include <iostream>#include <cstdio>using namespace std;typedef long long LL;#define MOD 300007#define MAXN 1000000struct node{LL per_sum;char ch;LL count;int next;};struct Hash{int Table[MOD],cnt;node List[MAXN];void Clear(){cnt=0;for(int i=0;i<MOD;i++)Table[i]=-1;}void Insert(LL sum,char ch){LL hash=sum+ch;if(hash<0)hash=-hash;hash=hash%MOD;LL temp=hash;temp=Table[hash];while(temp!=-1){if(List[temp].per_sum==sum && List[temp].ch==ch){List[temp].count++;return ;}temp=List[temp].next;}List[cnt].ch=ch;List[cnt].per_sum=sum;List[cnt].count=1;List[cnt].next=Table[hash];Table[hash]=cnt;cnt++;}LL Search(LL sum,char ch){LL hash=sum+ch;if(hash<0)hash=-hash;hash=hash%MOD;hash=Table[hash];while(hash!=-1){if(List[hash].ch==ch && List[hash].per_sum==sum)return List[hash].count;hash=List[hash].next;}return 0;}}H;char str[100010];LL sum[1000010];int main(){H.Clear();int weight[30],i,j,k;LL ans=0;for(i=0;i<26;i++)scanf("%d",&weight[i]);scanf("%s",str);sum[0]=weight[str[0]-'a'];for(i=1;str[i]!='\0';i++)sum[i]=sum[i-1]+weight[str[i]-'a'];H.Insert(sum[0],str[0]);for(i=1;str[i]!='\0';i++){ans+=H.Search(sum[i-1],str[i]);H.Insert(sum[i],str[i]);}cout<<ans<<'\n';return 0;}

map版,更清爽,不过慢一点

#include <iostream>#include <map>#include <cstdio>using namespace std;typedef long long LL;char str[100010];int main(){map <LL,int> mp[26];LL s[26],i,j,ans=0,sum=0;for(i=0;i<26;i++)cin>>s[i];scanf("%s",str);for(i=0;str[i];i++){ans+=mp[str[i]-'a'][sum];sum+=s[str[i]-'a'];mp[str[i]-'a'][sum]++;}cout<<ans<<"\n";return 0;}


0 0
原创粉丝点击