BNUOJ 52317 As Easy As Possible 树上倍增/主席树
题目链接:
https://acm.bnu.edu.cn/v3/problem_show.php?pid=52317
As Easy As Possible
Case Time Limit: 1000msMemory 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 树上倍增/主席树的更多相关文章
- 【BZOJ 3551】[ONTAK2010] Peaks加强版 Kruskal重构树+树上倍增+主席树
这题真刺激...... I.关于Kruskal重构树,我只能开门了,不过补充一下那玩意还是一棵满二叉树.(看一下内容之前请先进门坐一坐) II.原来只是用树上倍增求Lca,但其实树上倍增是一种方法,L ...
- 【codeforces666E】Forensic Examination 广义后缀自动机+树上倍增+线段树合并
题目描述 给出 $S$ 串和 $m$ 个 $T_i$ 串,$q$ 次询问,每次询问给出 $l$ .$r$ .$x$ .$y$ ,求 $S_{x...y}$ 在 $T_l,T_{l+1},...,T_r ...
- 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 ...
- 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 ...
- (2016北京集训十三)【xsy1532】网络战争 - 最小割树+树上倍增+KD树
题解: 好题!! 这题似乎能上我代码长度记录的前五? 调试时间长度应该也能上前五QAQ 首先题目要求的明显就是最小割,当然在整个森林上求Q次最小割肯定是会GG的,所以我们需要一个能快速求最小割的算法— ...
- HDU 4729 An Easy Problem for Elfness (主席树,树上第K大)
转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove 题意:给出一个带边权的图.对于每一个询问(S , ...
- BZOJ4771 七彩树(dfs序+树上差分+主席树)
考虑没有深度限制怎么做.显然的做法是直接转成dfs序上主席树,但如果拓展到二维变成矩形数颜色数肯定没法做到一个log. 另一种做法是利用树上差分.对于同种颜色的点,在每个点处+1,dfs序相邻点的lc ...
- BZOJ4539 [Hnoi2016]树 【倍增 + 主席树】
题目链接 BZOJ4539 题解 我们把每次复制出来的树看做一个点,那么大树实际上也就是一棵\(O(M)\)个点的树 所以我们只需求两遍树上距离: 大树上求距离,进入同一个点后在模板树上再求一次距离 ...
- 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 ...
随机推荐
- 06_Java基础语法_第6天(自定义类、ArrayList集合)_讲义
今日内容介绍 1.自定义类型的定义及使用 2.自定义类的内存图 3.ArrayList集合的基本功能 4.随机点名器案例及库存案例代码优化 01引用数据类型_类 * A: 数据类型 * a: java ...
- 关于在MySql的decimal中犯的一个错-此篇文章目的在于警醒自己
今天在运行一段程序的时候报了Out of range value错误,网上的解释是说这个值与数据库字段类型不匹配,然而程序里面设置的是BigDecimal,数据库设置的是decimal,没有多想就把s ...
- Linux入门第二天——基本命令入门(上)
一.常用命令介绍 常见命令可参考:http://man.linuxde.net/ http://linux.51yip.com/ 请对照参考! 常用的快捷键:http://blog.csdn.net/ ...
- 20145209刘一阳《JAVA程序设计》第三周课堂测试
第三周课堂测试 1.使用汇编语言编写指令时,用一些简单的容易记忆的符号来代替二进制指令,比机器语言更为方便,属于高级语言.(B) A .true B .false 2.下列说法正确的是(ABCD) A ...
- jsp 中 , jq 获取当前所点击的 select 的 id 值的注意事项
因为是使用的 jstl 的 foreach ,所以每个 select 的 id 值都不同,要想在 change 方法中获取到 当前所点击的 select 的 id 值,需要注意的地方有: 1. 得到 ...
- window.location.hash 页面跳转,精确定位,实例展示:
window.location.hash 页面跳转,精确定位,实例展示: (1).index.phtml,页面用于传参 <script id="bb_list_template&quo ...
- [转载]MySQL面试题
1.MySQL的复制原理以及流程基本原理流程,3个线程以及之间的关联:(1)主:binlog线程——记录下所有改变了数据库数据的语句,放进master上的binlog中:(2)从:io线程——在使用s ...
- 010 --MySQL查询优化器的局限性
MySQL的万能"嵌套循环"并不是对每种查询都是最优的.不过还好,mysql查询优化器只对少部分查询不适用,而且我们往往可以通过改写查询让mysql高效的完成工作.在这我们先来看看 ...
- SICP读书笔记 2.5
SICP CONCLUSION 让我们举起杯,祝福那些将他们的思想镶嵌在重重括号之间的Lisp程序员 ! 祝我能够突破层层代码,找到住在里计算机的神灵! 目录 1. 构造过程抽象 2. 构造数据抽象 ...
- Aria2 Linux 完整安装及使用教程
Aria2 嘛,主要是用来离线下载,功能强大,支持 http/https 直链.ftp.电驴.磁力链接等等,且可以跨平台使用,配合网页端操作,简直是一代下载神器. 安装 Debian/Ubuntu: ...