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 ...
随机推荐
- Tarjan算法初探 (1):Tarjan如何求有向图的强连通分量
在此大概讲一下初学Tarjan算法的领悟( QwQ) Tarjan算法 是图论的非常经典的算法 可以用来寻找有向图中的强连通分量 与此同时也可以通过寻找图中的强连通分量来进行缩点 首先给出强连通分量的 ...
- JQuery中的事件委托
JQuery 中的事件委托 定义 事件委托就是利用冒泡的原理,把事件加到父级上,通过判断事件来源的子集,执行相应的操作,事件委托首先可以极大减少事件绑定次数,提高性能:其次可以让新元素的子元素也可以拥 ...
- 什么是websoket
概念 HTML5作为下一代WEB标准,拥有许多引人注目的新特性,如Canvas.本地存储.多媒体编程接口.WebSocket 等等.今天我们就来看看具有“Web TCP”之称的WebSocket. W ...
- PHPCMS v9 手机版如何设置独立域名
一.在PHPcms V9管理后台设置手机门户(目前phpcms v9 版本为V9.6.3) 1.1.开启手机网站.位置:模块 >手机门户 > 添加手机站点,具体设置可参照截图: 填写站点名 ...
- C中级 - 文件辅助操作
引言 - 业务有点麻烦 C 功能很强大, 同样书写起来会谨慎(拖泥带水). 不妨通过一个小问题来描述裹脚的 C 需求: 用 C 创建一个文件! 难点在于 1. 文件路径切割成 目录 + 文件名 2. ...
- tomcat启动慢?自己动手打造轻量web服务器(一)
废话少说,直接上代码. 编程语言:kotlin import java.net.ServerSocketimport java.net.Socket fun main(args:Array<St ...
- P2167 [SDOI2009]Bill的挑战
sb状压dp. 设f[i][j]表示字符串前i位和集合为j的串匹配的方案数. 枚举哪个字母直接转移就好了. (话说为啥这种水题都有紫色难度 #include<bits/stdc++.h> ...
- restful framework之频率组件
一.频率简介 为了控制用户对某个url请求的频率,比如,一分钟以内,只能访问三次 二.自定义频率类.自定义频率规则 自定义的逻辑 #(1)取出访问者ip # (2)判断当前ip不在访问字典里,添加进去 ...
- 报错:Cannot create PoolableConnectionFactory (The server time zone value 'CST' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverT
报错:Cannot create PoolableConnectionFactory (The server time zone value 'CST' is unrecognized or repr ...
- vue.js和vue-router和vuex快速上手知识
vue.js和vue-router和vuex快速上手知识 一直以来,认为vue相比react而言,学习成本会更低,会更简单,但最近真正接触后,发现vue的各方面都有做一些客户化的优化,有一些亮点,但也 ...