题目链接:

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. h5声音录制/播放

    html代码: <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" ...

  2. mac 下安装php7.1 memcache扩展

    1.下载memcache源代码文件 https://github.com/websupport-sk/pecl-memcache/archive/php7.zip 文件夹名为:pecl-memcach ...

  3. 大数据入门:Hadoop安装、环境配置及检测

    目录 1.导包Hadoop包 2.配置环境变量 3.把winutil包拷贝到Hadoop bin目录下 4.把Hadoop.dll放到system32下 5.检测Hadoop是否正常安装 5.1在ma ...

  4. 20155239吕宇轩 Linux下IPC机制

    20155239吕宇轩 Linux下IPC机制 - 共享内存 原理:把所有需要使用的共享数据都存放在共享内存 区域中,任何想要访问这些共享数据的进程都必须在自己的进程地址空间中新增加一块内存区域,用来 ...

  5. wpf mediakit 摄像头截图

    原文:wpf mediakit 摄像头截图 在用VideoCaptureElement的过程中,不知道怎么获得摄像头的截图,纠结了整整一天, 最终在下面的网站上找到了答案,哈哈.(困的都不清醒的大脑, ...

  6. LVM Linear vs Striped Logical Volumes

    转自:https://sysadmincasts.com/episodes/27-lvm-linear-vs-striped-logical-volumes About Episode - Durat ...

  7. matplotlib 代码风格

    当查看 matplotlib 官方文档和示例时,你会发现不同的编码风格和使用模式.这些风格是完全有效的,各有其优缺点. 几乎所有的例子都可以转换成另一种风格,以实现相同的结果.当然,需要注意的是不要把 ...

  8. [FJOI2015]火星商店问题

    [FJOI2015]火星商店问题 神仙线段树分治...不过我不会. 这题用线段树套可持久化Trie还是能写的. 常数有点大,洛谷垫底水平. // luogu-judger-enable-o2 #inc ...

  9. jquery ajax 上传文件和传递参数到一个接口的实现方法

    参考:https://blog.csdn.net/qq_15674631/article/details/81095284 参考:https://www.jianshu.com/p/46e6e03a0 ...

  10. Vue实例 中的常用配置项

    创建Vue实例时,使用 new Vue ({//配置项}) 或者 组件定义中 export default {//配置项},所有的Vue组件都是Vue实例,并且接受相同的选项对象(一些根实例特有的选项 ...