博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
区间 GCD
阅读量:6611 次
发布时间:2019-06-24

本文共 2382 字,大约阅读时间需要 7 分钟。

区间 GCD

题目描述
最近 JC 同学刚学会 gcd,于是迷上了与 gcd 有关的问题。今天他又出了一道这样的题目,
想要考考你,你能顺利完成吗?
给定一个长度为 n 的字符串 s[1..n],串仅包含小写字母。对于区间 [l, r],你需要回答 s[l..r]
中有多少个长度为 3 的子序列组成了"gcd",即有多少组 (i, j, k) 满足 l ≤ i < j < k ≤ r, s[i] =
'g', s[j] = 'c', s[k] = 'd'。
输入格式
第一行为一个字符串 s。
第二行为一个整数 q,表示询问数量。
接下来 q 行,每行两个整数 l i , r i ,表示一组询问。
输出格式
输出共 q 行,表示每一组询问的答案。答案请对 2 31 取模后输出。
样例输入
glygshcyjcdzy
3
1 11
2 11
2 10
样例输出
4
2
0
数据规模与约定
对于 20% 的数据,n ≤ 300, q = 1。
对于 40% 的数据,n ≤ 300, q ≤ 300。
对于 70% 的数据,n ≤ 4000, q ≤ 4000。
对于 100% 的数据,n ≤ 80000, q ≤ 80000。
串仅包含小写字母。1 ≤ l i ≤ r i ≤ n。

 

题解:

  这个题目仔细想想其实是考试里最简单的一道题,但还是让我很有启发。

  首先,我们考虑维护区间的g,c,d,gc,cd,gcd的个数,怎么维护呢?

  g,c,d可以直接统计,如果用线段树做的话,gc的个数=ls的gc数+rs的gc+ls]的g数*rs的c数,cd数同理,然后gcd数了,gcd数=ls的gcd+rs的gcd+ls的gc*rs的d+ls的g*rs的cd;其实这样讲的话感觉就一点也不神奇,很理所当然了,但是至少启发我们线段树中可以理由递推关系记一些元素推出一些元素。当然返回的时候返回的是结构题。

 

代码:

#include 
#include
#include
#include
#include
#include
#define ll long long#define MAXN 80100using namespace std;int sum[MAXN],len,q;ll ans=0,mod=(ll)1<<31;char s[MAXN];struct tree{ ll g,c,d,gc,cd,gcd; int l,r;}a[MAXN*4];void pushup(int xv){ int ls=xv*2,rs=xv*2+1; a[xv].g=a[ls].g+a[rs].g; a[xv].c=a[ls].c+a[rs].c; a[xv].d=a[ls].d+a[rs].d; a[xv].cd=(a[ls].cd+a[rs].cd+a[ls].c*a[rs].d)%mod; a[xv].gc=(a[ls].gc+a[rs].gc+a[ls].g*a[rs].c)%mod; a[xv].gcd=(a[ls].gcd+a[rs].gcd+a[ls].gc*a[rs].d+a[ls].g*a[rs].cd)%mod;}void build(int xv,int l,int r){ if(l==r){ a[xv].l=l,a[xv].r=r; a[xv].g=a[xv].d=a[xv].c=a[xv].gc=a[xv].cd=0; if(s[l]=='g') a[xv].g=1; if(s[l]=='c') a[xv].c=1; if(s[l]=='d') a[xv].d=1; return; } a[xv].l=l,a[xv].r=r; int mid=(l+r)/2; build(xv*2,l,mid); build(xv*2+1,mid+1,r); pushup(xv);}tree query(int xv,int l,int r){ int L=a[xv].l,R=a[xv].r,mid=(L+R)/2; if(l==L&&r==R){ return a[xv]; } if(r<=mid) return query(xv*2,l,r); else if(l>mid) return query(xv*2+1,l,r); else { tree ls=query(xv*2,l,mid),rs=query(xv*2+1,mid+1,r),xvv; xvv.g=ls.g+rs.g; xvv.c=ls.c+rs.c; xvv.d=ls.d+rs.d; xvv.cd=(ls.cd+rs.cd+ls.c*rs.d)%mod; xvv.gc=(ls.gc+rs.gc+ls.g*rs.c)%mod; xvv.gcd=(ls.gcd+rs.gcd+ls.gc*rs.d+ls.g*rs.cd)%mod; return xvv; }}int main(){ scanf("%s",s+1); len=strlen(s+1); build(1,1,len); scanf("%d",&q); while(q--){ int l,r;scanf("%d%d",&l,&r); printf("%lld\n",query(1,l,r).gcd%mod); } return 0;}

 

转载于:https://www.cnblogs.com/renjianshige/p/7521570.html

你可能感兴趣的文章
ORACLE expdp备份与ORA-31693、ORA-02354、ORA-02149
查看>>
DBMS_STATS.GATHER_TABLE_STATS
查看>>
Java-单机版的书店管理系统(练习设计模块和思想_系列 五 )
查看>>
嵌入式 详解udev
查看>>
《C程序员:从校园到职场》出版预告(2):从“百花齐放”到“一枝独秀”
查看>>
Network Monitor 查询命令和MySQL命令
查看>>
好“戏”刚刚开幕 云计算逐步被认可
查看>>
云安全:这也是需要花大钱去建设的部分
查看>>
以全局产业观领航智慧城市建设
查看>>
5G网络不止能1秒下一部电影,它还能够…
查看>>
中国电信集采终端6700万部 金额达1070亿元
查看>>
2016年的十个数据中心故事
查看>>
《Java并发编程的艺术》一一3.3 顺序一致性
查看>>
《CCNP SWITCH 300-115认证考试指南》——导读
查看>>
《设计之外——比修图更重要的111件事》—第1部分3 虚心学习
查看>>
Solaris Studio 12.4 Beta update 7/2014
查看>>
EVCache —— Netflix 的分布式内存数据存储
查看>>
《用友ERP-U8(8.72版)标准财务模拟实训》——1.4 系统管理注册和导入演示账套...
查看>>
《Node.js区块链开发》一3.6 总结
查看>>
《UG NX8.0中文版完全自学手册》一2.8 布尔运算
查看>>