题目链接:

https://acm.bnu.edu.cn/v3/problem_show.php?pid=52317

As Easy As Possible

Case Time Limit: 1000ms
Memory Limit: 524288KB
## 题意
> 给你一个只含'e','a','s','y'的字符串,问你区间[l,r]内像"easyeasyeasy"这样的最多"easy"重复的子序列,输出easy重复的次数。

题解

1、用倍增的思路来做,每个点只记录最靠近它的在它左边的那个字母的位置,比如'e'记录前面的'y','a'记录前面的'e','s'记录前面的'a'...。这样相当于得到了一些树形结构,用树上倍增的思路去做就可以了。

具体的看代码比较好理解。

其实主要的思路就是化整为0,对每个字母只考虑排在它前面的且最靠近它的在它左边的那个字母的位置。然后你发现这个就可以用树上倍增来快速求我们需要的子序列了。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std; const int maxn=101010;
const int maxm=22; char str[maxn];
int arr[maxn],p3[maxn];
int n,m;
int anc[maxn][maxm];
int mp[4]; int main(){
scanf("%s",str+1);
n=strlen(str+1);
for(int i=1;i<=n;i++){
if(str[i]=='e') arr[i]=0;
else if(str[i]=='a') arr[i]=1;
else if(str[i]=='s') arr[i]=2;
else if(str[i]=='y') arr[i]=3;
} ///mp[i]存数字i最后出现的位置
memset(mp,0,sizeof(mp));
for(int i=1;i<=n;i++){
int pre=(arr[i]-1+4)%4;
anc[i][0]=mp[pre];
mp[arr[i]]=i;
p3[i]=mp[3];
} memset(anc[0],0,sizeof(anc[0])); for(int j=1;j<maxm;j++){
for(int i=1;i<=n;i++){
anc[i][j]=anc[anc[i][j-1]][j-1];
}
} scanf("%d",&m);
while(m--){
int l,r;
scanf("%d%d",&l,&r);
int v=p3[r];
int res=1;
for(int j=maxm-1;j>=0;j--){
if(anc[v][j]>=l){
v=anc[v][j];
res+=1<<j;
}
}
printf("%d\n",res/4);
} return 0;
}

2、主席树:

从前晚后建树,如果单前不是'y',那么rt[i]=rt[i-1],如果是的话,就贪心匹配,找到左边最接近的"eas",rt[i]=rt['e'前一个位置-1],然后把e的位置插到rt[i]这颗线段树中。

对于查询[l,r],直接去rt[r]中查找区间(l,r)的和就可以了。

相当于每颗线段树rt[i]维护了以i为结尾的区间的往左边贪心的最长"easyeasyeasy..."的子串。

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson(i) (tre[(i)].ls)
#define rson(i) (tre[(i)].rs)
#define sumv(i) (tre[(i)].sum)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)
#define scf scanf
#define prf printf typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII; const int INF=0x3f3f3f3f;
const LL INFL=0x3f3f3f3f3f3f3f3fLL;
const double eps=1e-8;
const double PI = acos(-1.0); //start---------------------------------------------------------------------- const int maxn=101010; ///nlogn空间复杂度
struct Tre {
int ls,rs,sum;
Tre() {
ls=rs=sum=0;
}
} tre[maxn*20]; int rt[maxn],tot; int _pos;
void update(int &o,int l,int r) {
tre[++tot]=tre[o],o=tot;
if(l==r) {
sumv(o)++;
} else {
if(_pos<=mid) update(lson(o),l,mid);
else update(rson(o),mid+1,r);
sumv(o)=sumv(lson(o))+sumv(rson(o));
}
} int _res,ql,qr;
void query(int o,int l,int r){
if(ql<=l&&r<=qr){
_res+=sumv(o);
}else{
if(ql<=mid) query(lson(o),l,mid);
if(qr>mid) query(rson(o),mid+1,r);
}
} char str[maxn];
int n,m; void init(){
rt[0]=tot=0;
} int solve(int pos){
int pre=0;
while(pos>0){
if(str[pos]=='s'&&pre==0) pre=1;
else if(str[pos]=='a'&&pre==1) pre=2;
else if(str[pos]=='e'&&pre==2) pre=3;
if(pre==3) break;
pos--;
}
return pos;
} int main() {
scf("%s",str+1);
n=strlen(str+1);
init();
for(int i=1;i<=n;i++){ if(str[i]=='y'){
_pos=solve(i-1);
if(_pos>0){
rt[i]=rt[_pos-1];
update(rt[i],1,n);
}else{
rt[i]=rt[i-1];
}
}else{
rt[i]=rt[i-1];
}
} scf("%d",&m);
while(m--){
int l,r;
scf("%d%d",&l,&r);
ql=l,qr=r,_res=0;
query(rt[r],1,n);
prf("%d\n",_res);
} return 0;
} //end-----------------------------------------------------------------------

BNUOJ 52317 As Easy As Possible 树上倍增/主席树的更多相关文章

  1. 【BZOJ 3551】[ONTAK2010] Peaks加强版 Kruskal重构树+树上倍增+主席树

    这题真刺激...... I.关于Kruskal重构树,我只能开门了,不过补充一下那玩意还是一棵满二叉树.(看一下内容之前请先进门坐一坐) II.原来只是用树上倍增求Lca,但其实树上倍增是一种方法,L ...

  2. 【codeforces666E】Forensic Examination 广义后缀自动机+树上倍增+线段树合并

    题目描述 给出 $S$ 串和 $m$ 个 $T_i$ 串,$q$ 次询问,每次询问给出 $l$ .$r$ .$x$ .$y$ ,求 $S_{x...y}$ 在 $T_l,T_{l+1},...,T_r ...

  3. BZOJ 2588: Spoj 10628. Count on a tree 树上跑主席树

    2588: Spoj 10628. Count on a tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/J ...

  4. SPOJ 10628 COT - Count on a tree(在树上建立主席树)(LCA)

    COT - Count on a tree #tree You are given a tree with N nodes.The tree nodes are numbered from 1 to ...

  5. (2016北京集训十三)【xsy1532】网络战争 - 最小割树+树上倍增+KD树

    题解: 好题!! 这题似乎能上我代码长度记录的前五? 调试时间长度应该也能上前五QAQ 首先题目要求的明显就是最小割,当然在整个森林上求Q次最小割肯定是会GG的,所以我们需要一个能快速求最小割的算法— ...

  6. HDU 4729 An Easy Problem for Elfness (主席树,树上第K大)

    转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove 题意:给出一个带边权的图.对于每一个询问(S , ...

  7. BZOJ4771 七彩树(dfs序+树上差分+主席树)

    考虑没有深度限制怎么做.显然的做法是直接转成dfs序上主席树,但如果拓展到二维变成矩形数颜色数肯定没法做到一个log. 另一种做法是利用树上差分.对于同种颜色的点,在每个点处+1,dfs序相邻点的lc ...

  8. BZOJ4539 [Hnoi2016]树 【倍增 + 主席树】

    题目链接 BZOJ4539 题解 我们把每次复制出来的树看做一个点,那么大树实际上也就是一棵\(O(M)\)个点的树 所以我们只需求两遍树上距离: 大树上求距离,进入同一个点后在模板树上再求一次距离 ...

  9. HDU 4729 An Easy Problem for Elfness(主席树)(2013 ACM/ICPC Asia Regional Chengdu Online)

    Problem Description Pfctgeorge is totally a tall rich and handsome guy. He plans to build a huge wat ...

随机推荐

  1. C++程序设计入门 之常量学习

    常量: 常量的定义格式:const datatype CONSTANTNAME = VALUE 常量的命名规范:符号常量(包括枚举值)必须全部大写并用下划线分隔单词 例如:MAX_ITERATIONS ...

  2. shiro配置说明

    Shiro主要是通过URL过滤来进行安全管理,这里的配置便是指定具体授权规则定义. Xml代码   <bean id="shiroFilter" class="or ...

  3. css文字环绕

    html: <div class="wrap-div-topSpacer"></div> <div class="wrap-div" ...

  4. const限定符用法汇总

    const限定符限定变量的类型是一个常量,对象一旦创建后其值就无法改变,所以const对象必须初始化. 初始化 const int i = get_size(); //运行时初始化 const int ...

  5. Ubuntu14.04 64位机上安装OpenCV2.4.13(CUDA8.0)版操作步骤

    Ubuntu14.04 64位机上安装CUDA8.0的操作步骤可以参考http://blog.csdn.net/fengbingchun/article/details/53840684,这里是在已经 ...

  6. 【Vijos】lxhgww的奇思妙想

    题面 题解 求$k$级祖先孙子 为什么要用长链剖分啊??? 倍增并没有慢多少... 其实是我不会 长链剖分做这道题还是看这位巨佬的吧. 代码 #include<bits/stdc++.h> ...

  7. C#用Oracle.DataAccess中连接Oracle要注意版本问题!转)

    一般人,不包括全部平时在开发中使用的都是32位的PC机,所以安装的也是Oracle32位的客户端.但是一般服务器都是64位的,安装的也是 64位的Oracle客户端,如果要部署使用Oracle.Dat ...

  8. unity灯光烘焙设置详解

    游戏场景中灯光照明的构成 现实生活中的光线是有反射.折射.衍射等特性的.对这些基本特性的模拟一直以来都是计算机图形图像学的重要研究方向. 在CG中,默认的照明方式都是不考虑这些光线特性的,因此出来的效 ...

  9. python中web应用与mysql数据库交互

    7使用数据库 具体使用python的DB-API,这一章里介绍如何编写代码与MYSQL数据库技术交互,这里使用一个通用的数据库API,名为DB-API. 7.1基于数据库的web应用 之前我们把日志数 ...

  10. 如何在window服务器上搭建一个能代替ftp的传输工具

    通常对于服务器上的文件管理和数据传输都是利用ftp来实现,但随着存储技术的发展,数据资产的存储规模和复杂程度不断提高,传统的ftp传输显得有笨重.今天给大家介绍一款能够取代ftp的在线文档管理软件—— ...