Codeforces Round #294 Div2 D(A and B and Interesting Substrings)

Problem

给一个长度为N的字符串S,字符集是[a,z],每个字符都有一个权值Vi,求有多少个子串subS满足以下条件:

1. |subS|>=2

2. subS[0]=subS[|subS|?1]

3. ∑|subS|?2i=1Vi=0

Limits

TimeLimit(ms):2000

MemoryLimit(MB):256

N∈[1,105]

Vi∈[?105,105]

Look up Original Problem From here

Solution

如果没有条件2,用前缀和思想可做。定义map:m[i]表示前缀和的权值为 i 的有多少个,从左往右扫N个前缀和,当前扫到的前缀和权值为i,则查询m[i],那么就有m[i]个子串为0,再更新map…

加上条件2,用26个map即可…

Complexity

TimeComplexity:O(N×log2N)

MemoryComplexity:O(N)

My Code

//Hello. I‘m Peter.
#include<cstdio>
#include<iostream>
#include<sstream>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<cctype>
#include<ctime>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
#define peter cout<<"i am peter"<<endl
#define input freopen("data.txt","r",stdin)
#define randin srand((unsigned int)time(NULL))
#define INT (0x3f3f3f3f)*2
#define LL (0x3f3f3f3f3f3f3f3f)*2
#define gsize(a) (int)a.size()
#define len(a) (int)strlen(a)
#define slen(s) (int)s.length()
#define pb(a) push_back(a)
#define clr(a) memset(a,0,sizeof(a))
#define clr_minus1(a) memset(a,-1,sizeof(a))
#define clr_INT(a) memset(a,INT,sizeof(a))
#define clr_true(a) memset(a,true,sizeof(a))
#define clr_false(a) memset(a,false,sizeof(a))
#define clr_queue(q) while(!q.empty()) q.pop()
#define clr_stack(s) while(!s.empty()) s.pop()
#define rep(i, a, b) for (int i = a; i < b; i++)
#define dep(i, a, b) for (int i = a; i > b; i--)
#define repin(i, a, b) for (int i = a; i <= b; i++)
#define depin(i, a, b) for (int i = a; i >= b; i--)
#define pi 3.1415926535898
#define eps 1e-9
#define MOD 1000000007
#define MAXN 2015
#define N 100100
#define M
map<ll,ll>countit[30];
map<ll,ll>::iterator it;
ll letterpoints[30],now,ans;
ll points(char c){
    return letterpoints[c-‘a‘];
}
int lens;
char s[N];
int main(){
    rep(i,0,26){
        scanf("%lld",letterpoints+i);
    }
    scanf("%s",s);
    lens=len(s);
    now=points(s[0]);
    ans=0;
    countit[s[0]-‘a‘][now]+=1LL;
    rep(i,1,lens){
        ans+=countit[s[i]-‘a‘][now];
        now+=points(s[i]);
        countit[s[i]-‘a‘][now]+=1LL;
    }
    cout<<ans<<endl;
}
时间: 2024-10-19 22:58:05

Codeforces Round #294 Div2 D(A and B and Interesting Substrings)的相关文章

Codeforces Round #294 Div2 E(A and B and Lecture Rooms)

Problem 给一棵树,含有N个节点,N?1条边.进行M次查询,每次给定两个节点x,y,问树上有多少个节点到x,y的距离相同. Limits TimeLimit(ms):2000 MemoryLimit(MB):256 N,M∈[1,105] x,y∈[1,N] Look up Original Problem From here Solution 求出a,b两个节点的lca,再找到lca?>a或lca?>b上的某个节点v使得dis(v,a)=dis(v,b).分v=lca,v∈lca?&g

Codeforces Round #287 Div2 D(The Maths Lecture)

Problem 长度为N的数X(十进制),如果X的某一段后缀Y(十进制)可被k整除,则可被统计.问有多少这样的X?(mod m)(不可含前导0) Limits TimeLimit(ms):1000 MemoryLimit(MB):256 N:∈[1,1000] k∈[1,100] m∈[1,109] Look up Original Problem From here Solution 数位dp.设dp[i][j]表示数长度为 i 且数mod k 为 j时, 有多少个.dp[i][0]不要往前转

Codeforces Round #293 Div2 E(Arthur and Questions)

Problem Limits TimeLimit(ms):2000 MemoryLimit(MB):256 k,n∈[1,105],k<=n ai∈[?109,109] Look up Original Problem From here Solution 要满足数列bn单调递增.b1<b2,则a1+a2+-+ak<a2+-+ak+ak+1,即a1<ak+1,依此类推,a2<ak+2,a3<ak+3,-,ai<ak+i,-,这样子我们就可以把an划分成若干条链,每

Codeforces Round #293 Div2 F(Pasha and Pipe)

Problem Limits TimeLimit(ms):4000 MemoryLimit(MB):512 n,m∈[2,2000] Look up Original Problem From here Solution 一共就14种情况.有些情况可以合并一起算,算出来就好了. Complexity TimeComplexity:O(n×m) MemoryComplexity:O(n×m) My Code //Hello. I'm Peter. #include<cstdio> #includ

codeforces round#259 div2 B题(KMP)

先上链接:http://codeforces.com/contest/454/problem/B B. Little Pony and Sort by Shift time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output One day, Twilight Sparkle is interested in how to sort a se

codeforces round #257 div2 C、D

本来应该认真做这场的,思路都是正确的. C题,是先该横切完或竖切完,无法满足刀数要求,再考虑横切+竖切(竖切+横切), 因为横切+竖切(或竖切+横切)会对切割的东西产生交叉份数,从而最小的部分不会尽可能的大. 代码如下,虽然比较长.比较乱,但完全可以压缩到几行,因为几乎是4小块重复的代码,自己也懒得压缩 注意一点,比如要判断最小块的时候,比如9行要分成2份,最小的剩下那份不是9取模2,而应该是4 m/(k+1)<=m-m/(k+1)*k          #include<bits/stdc+

Codeforces Round #260(div2)C(递推)

有明显的递推关系: f[i]表示i为数列中最大值时所求结果.num[i]表示数i在数列中出现了几次. 对于数i,要么删i,要么删i-1,只有这两种情况,且子问题还是一样的思路.那么很显然递推一下就行了:f[i]=max(f[i-1],f[i-2]+i*num[i]); 这里技巧在于:为了防止麻烦,干脆就所有数的出现次数都记录一下,然后直接从2推到100000(类似于下标排序),就不用排序了,也不用模拟删除操作了.这一技巧貌似简单,但实际上临场想出来也需要点水平. #include<iostrea

CodeForces Round#229 DIV2 C 递推DP

对这道题目也只好说呵呵了,没注意k的范围最大才10,所以昨晚纠结了很久,没什么好的方法来处理,后来无奈想去翻翻题解,发现人家开头就来了句,因为k的范围比较小 所以.........我只好暂停马上回头看看题目,是的,k比较小所以完全可以先在询问前预处理DP一遍, DP就比较清晰了,dp[i][j]  (i>=0 && i<k,,,,j>=i && j <=n)代表意义呢 以i为开头的  区间[1,j]注意 是 1~j的 所需要的操作数,题目问的是最小操

【前行】◇第3站◇ Codeforces Round #512 Div2

[第3站]Codeforces Round #512 Div2 第三题莫名卡半天……一堆细节没处理,改一个发现还有一个……然后就炸了,罚了一啪啦时间 Rating又掉了……但是没什么,比上一次好多了:) +传送门+ ◇ 简单总结 前两道题非常OK,秒掉还好.心态爆炸是从第三题开始的……一开始设计的判断方法没有考虑0,然后就错了很多次,然后改了过后又没有考虑整个数要分成2个及以上的数,继续WA,最后整个程序删了重新魔改了一次终于AC.感觉最后的AC代码的复杂度要比原来高一些,但是毕竟AC了,还是不