码迷,mamicode.com
首页 > 其他好文 > 详细

区间GCD

时间:2017-08-02 13:57:43      阅读:155      评论:0      收藏:0      [点我收藏+]

标签:gif   scanf   logs   url   ges   范围   枚举   code   display   

技术分享

 

输入格式:

技术分享

输出格式:

技术分享

样例输入:

glygshcyjcdzy
3
1 11
2 11
2 10

 

样例输出:

4
2
0

 

数据范围:

技术分享

 

时间限制:

3S

 

空间限制:

512MB

 

这题是一个统计题.如果只是两个字母,那就很好做了,然而,三个字母的话,很难直接统计.如果枚举g,还药确定c,d的相对位置,枚举c和d也同样.更何况有Q次询问.

想到这题又是有多次询问,也没有修改操作,而且能在知道[L,R](或[L+1,R+1])的情况下知道[L+1,R]和[L,R+1],所以,我们确定,这题非常适合分块+莫队.更何况,时间复杂度也就在这个级别.

不会莫队的童鞋请自行baidu一下(这一题有多种解法,如线段树).

对于这一题,我们做莫队的核心就是add和remove函数.

我们设g,c,d,gc,cd,gcd分别为这些串(g,c,d,gc,cd,gcd)在当前区间出现的次数.

如果来了一个字母或走了一个字母g,c,d,gc,cd,gcd要相应的更新,具体是什么关系,思考一下就出来了,不在赘述(本蒟蒻不想丢人现眼qwq).

技术分享
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<iostream>
 5 #include<cmath>
 6 #define LL long long
 7 using namespace std;
 8 const int maxn=80005;
 9 struct queries{int L,R,index; LL ans;}a[maxn];
10 char s[maxn];
11 int n,blocks,Q;
12 LL g,c,d,gc,cd,gcd,TT;
13 int read(){
14     int x=0; char ch=getchar();
15     while (ch<0||ch>9) ch=getchar();
16     while (ch>=0&&ch<=9) x=x*10+ch-0,ch=getchar();
17     return x;
18 }
19 bool cmp(queries u,queries v){return u.L/blocks==v.L/blocks?u.R<v.R:u.L<v.L;}
20 bool cmp_id(queries u,queries v){return u.index<v.index;}
21 void removeL(int p,int q){
22     if (s[p]==g) g--,gc-=c,gcd-=cd; else
23     if (s[p]==c) c--,cd-=d; else
24     if (s[p]==d) d--;
25 }
26 void removeR(int p,int q){
27     if (s[q]==d) d--,cd-=c,gcd-=gc; else
28     if (s[q]==c) c--,gc-=g; else
29     if (s[q]==g) g--;
30 }
31 void addL(int p,int q){
32     if (s[p]==g) g++,gc+=c,gcd+=cd; else
33     if (s[p]==c) c++,cd+=d; else
34     if (s[p]==d) d++;
35 }
36 void addR(int p,int q){
37     if (s[q]==d) d++,cd+=c,gcd+=gc; else
38     if (s[q]==c) c++,gc+=g; else
39     if (s[q]==g) g++;
40 }
41 int main(){
42     scanf("%s",s),n=strlen(s),blocks=sqrt(n),TT=(LL)2147483648LL;
43     for (int i=n; i>=1; i--) s[i]=s[i-1]; s[0]=0;
44     cin>>Q;    for (int i=1; i<=Q; i++) a[i].L=read(),a[i].R=read(),a[i].index=i;
45     sort(a+1,a+1+Q,cmp);
46     int curL=1,curR=0; g=c=d=gc=cd=gcd=0;
47     for (int i=1; i<=Q; i++){
48         while (curL<a[i].L) removeL(curL++,curR);
49         while (curR>a[i].R) removeR(curL,curR--);
50         while (curL>a[i].L) addL(--curL,curR);
51         while (curR<a[i].R) addR(curL,++curR);
52         a[i].ans=gcd%TT;
53     }
54     sort(a+1,a+1+Q,cmp_id); 
55     for (int i=1; i<=Q; i++) printf("%lld\n",a[i].ans);
56     return 0;
57 }
View Code

 

区间GCD

标签:gif   scanf   logs   url   ges   范围   枚举   code   display   

原文地址:http://www.cnblogs.com/whc200305/p/7273424.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!