P16592 [GKS 2016 #E] Diwali lightings 题解

题目大意

给你一个由字符 B 和 R 的组成的字符串 \(S\),设由无数个字符串 \(S\) 连接组成的字符串为 \(Z\),问从第 \(I\) 个字符到第 \(J\) 个字符中有几个 B。

思路分析

多组询问、求区间和,这一看就是前缀和。但是如果硬枚举的话,肯定会超时。

既然字符串 \(Z\) 是由无数个字符串 \(S\) 连接组成的,那么肯定会有很多重复的部分。

而这段重复的部分显然可以不用一个一个算,而是算出其中一个的目标字符的数量,然后乘上出现的完整周期数量,再加上剩余的字符里出现目标字符的次数,这就是算一个前缀里目标字符出现次数的方法。

算区间和用前缀和的原理算就行了。

#include<bits/stdc++.h>
using namespace std;
string s;
long long ans=0,num=0,n;//不开longlong___
long long getans(long long x){//求前缀和
   long long anss=x/n*num;//完整周期数量
   for(int i=1;i<=x%n;i++){//剩余的
      anss+=(s[i]=='B');
   }
   return anss;
}
int main(){
   std::ios::sync_with_stdio(0);
   cin.tie(0),cout.tie(0);
   int T;
   cin>>T;
   for(int id=1;id<=T;id++){
      ans=num=0;
      long long I,J;
      cin>>s>>I>>J;
      n=s.size();
      s=" "+s;
      for(int i=1;i<=n;i++){
         if(s[i]=='B')num++;//统计一个周期的目标字符数量
      }
      long long r=getans(J),l=getans(I-1);
      cout<<"Case #"<<id<<": "<<r-l<<'\n';//前缀和
   }
   return 0;
}
posted @ 2026-10-17 19:09  SCX2014  阅读(2)  评论(0)    收藏  举报