COCI CONTEST #1 18.10.2014 T3 PIRAMIDA

第三题:金字塔
zoran和tomislav闲来无事,他们玩这样一个游戏。zoran在院子里建了一个高度为n的(n>=1,n<=10^18)金字塔,然后写下一个他们最喜欢的单词。他们从金字塔的顶端开始,一个字母字母的写,不断的重复写这个单词,且在每一行都会改变方向。比如第一行从左到右,第二行就从右到左。一直把金字塔的每个位置都写上字母。现在zoran有k个查询,每次查询给出一个整数i和字母c,表示问第i行字母c出现次数。
这里写图片描述
上图的单词为JANJETINA
输入格式:
第一行一个整数n。
第二行是一个单词,全部由大写字母组成。长度小于1000000。
第三行包含一个整数K(1<=K<=50000),表示查询次数
接下来K行,每行包含一个整数ai和一个字母ci。(1<=ai<=n,ci是一个大写字母)。
输出格式:
K行,其中第i行输出一个整数,表示在ai行出现字母ci的次数。
输入样例1:
6
JANJETINA
5
1 J
1 A
6 N
6 I
5 E
输出样例1:
1
0
2
1
1
输入样例2:
5
A
5
1 A
2 A
3 A
4 A
5 B
输出样例2:
1
2
3
4
0
输入样例3:
3
AB
3
2 A
2 B
3 B
输出样例3:
1
1
2

一般难度的题。考试的时候听错题了,导致数组开小了,过了7/10。。。
首先我们应该不难发现一个小性质,就是那个每一行改变方向其实没用。
因为查询的是一整行的次数。
定义len是字符串的长度。
维护字符串在每个字符出现次数的前缀和。cnt[i][j]表示第i个字母在字符串的前j个字符中出现了多少次。
然后对于每一次的查询,第ai行前面的ai-1行一共有ai*(ai-1)/2个字母,因此第ai行开始的字母的位置是ai*(ai-1)/2%len+1,结束的字母的位置是(ai*(ai-1)/2+ai)%len。这一段的长度很显然是ai。
所以如果ai < len,那么显然第ai这一排字符只是整个字符串的一部分。
如果ai > len,那么首先ai这一行字符肯定重复了ai/len次,每一次ci这个字符的出现次数是cnt[ci][len]。然后问题就转换成了ai < len。
接下来,如果开始的字母位置比结束的字母位置大,那么就说明是走完了一圈又走回来了。
如果开始的字母位置比结束的字母位置小,那就是直接减。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
long long n;
int k,len,cnt[26][1000010];//开long long会爆内存
char s[1000010];
int main()
{
    scanf("%I64d",&n);
    scanf("%s",s+1);
    len=strlen(s+1);
    for(int i=1;i<=len;++i)
    {
        cnt[s[i]-'A'][i]++;
        for(int j=0;j<26;++j)
            cnt[j][i]+=cnt[j][i-1];
    }
    scanf("%d",&k);
    for(int i=1;i<=k;++i)
    {
        char op[3];
        long long h,st,ed,ans=0;
        scanf("%I64d%s",&h,op);
        if(h%2)st=(((h-1)/2)%len)*(h%len)%len;//注意这里不要乘出long long了
        else st=((h-1)%len)*((h/2)%len)%len;
        ed=(st+h%len)%len;
        ans=cnt[op[0]-'A'][len]*(h/len);
        if(st<ed)ans+=(cnt[op[0]-'A'][ed]-cnt[op[0]-'A'][st]);//st<ed,直接ed-st
        else if(st>ed)//st>ed,就是len-st+ed-0
        {
            ans+=(cnt[op[0]-'A'][len]-cnt[op[0]-'A'][st]);
            ans+=cnt[op[0]-'A'][ed];
        }
        printf("%I64d\n",ans);
    }
}

你可能感兴趣的:(COCI CONTEST #1 18.10.2014 T3 PIRAMIDA)