As Easy As Possible 倍增法
来源:互联网 发布:卖汉服的淘宝店 编辑:程序博客网 时间:2024/05/16 05:16
As we know, the NTU Final PK contest usually tends to be pretty hard. Many teams got frustrated when participating NTU Final PK contest. So I decide to make the first problem as “easy” as possible. But how to know how easy is a problem? To make our life easier, we just consider how easy is a string.
Here, we introduce a sane definition of “easiness”. The easiness of a string is the maximum times of “easy” as a subsequence of it. For example, the easiness of “eeaseyaesasyy” is 2. Since “easyeasy” is a subsequence of it, but “easyeasyeasy” is too easy.
How to calculate easiness seems to be very easy. So here is a string s consists of only ‘e’, ‘a’, ‘s’, and ‘y’. Please answer m queries. The i-th query is a interval [li , ri ], and please calculate the easiness of s[li ..ri ].
Input
The first line contains a string s. The second line contains an integer m. Each of following m lines contains two integers li
, ri .
• 1 ≤ |s| ≤ 105
• 1 ≤ m ≤ 105
• 1 ≤ li ≤ ri ≤ |s|
• s consists of only ‘e’, ‘a’, ‘s’, and ‘y’
Output
For each query, please output the easiness of that substring in one line.
Sample input 1
easy
3
1 4
2 4
1 3
Sample output 1
1
0
0
Sample input 2
eeaseyaesasyy
4
1 13
2 12
2 10
3 11
Sample output 2
2
2
1
Here, we introduce a sane definition of “easiness”. The easiness of a string is the maximum times of “easy” as a subsequence of it. For example, the easiness of “eeaseyaesasyy” is 2. Since “easyeasy” is a subsequence of it, but “easyeasyeasy” is too easy.
How to calculate easiness seems to be very easy. So here is a string s consists of only ‘e’, ‘a’, ‘s’, and ‘y’. Please answer m queries. The i-th query is a interval [li , ri ], and please calculate the easiness of s[li ..ri ].
Input
The first line contains a string s. The second line contains an integer m. Each of following m lines contains two integers li
, ri .
• 1 ≤ |s| ≤ 105
• 1 ≤ m ≤ 105
• 1 ≤ li ≤ ri ≤ |s|
• s consists of only ‘e’, ‘a’, ‘s’, and ‘y’
Output
For each query, please output the easiness of that substring in one line.
Sample input 1
easy
3
1 4
2 4
1 3
Sample output 1
1
0
0
Sample input 2
eeaseyaesasyy
4
1 13
2 12
2 10
3 11
Sample output 2
2
2
1
0
题意:给出一个只含有'e' ,'a','s' ,'y' 四种字符的字符串,询问m次区间[ Li, Ri ]的子序列中形如easyeasy的字符串最多重复easy多少次。
我的做法是对于每一个位置先倒序处理一遍得到每一个'e'后面的第一个'a'的位置,每一个'a'后面的第一个's'的位置等等,还有每个字符后第一个'e'的位置,
再求出每个字符沿着'e','a','s','y'的循环往后走2^n步会到达的位置,然后先在给定区间内找到第一个'e'的位置再用倍增法往后移动统计走过了多少个easy,直到往后走4步就会越界,就暴力往后走3步看会不会越界,如果不会越界则统计数加1。
因为用倍增法走2^n(n>2)步后所在的位置的字符还是'e',所以可以直接统计出答案。
时间复杂度:O(nlogn)
队友的做法是分块,每一个块储存有多少个'easy'子序列,每个块第一个'easy'的子序列前一段是有否有'y','sy','asy'这样的子序列,每个块的最后一个'easy'子序列后是否有'e','ea','eas'这样的子序列,这样就可以完成块与块之间的转移。时间复杂度O(n*sqrt(n)),时限1s,也可以过这题。
我的代码:
#include <bits/stdc++.h>using namespace std;inline void read(int &x){ char ch; bool flag=false; for (ch=getchar();!isdigit(ch);ch=getchar())if (ch=='-') flag=true; for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar()); x=flag?-x:x;}inline void read(long long &x){ char ch; bool flag=false; for (ch=getchar();!isdigit(ch);ch=getchar())if (ch=='-') flag=true; for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar()); x=flag?-x:x;}inline void write(int x){ static const int maxlen=100; static char s[maxlen]; if (x<0) { putchar('-'); x=-x;} if(!x){ putchar('0'); return; } int len=0; for(;x;x/=10) s[len++]=x % 10+'0'; for(int i=len-1;i>=0;--i) putchar(s[i]);}inline void write(long long x){ static const int maxlen=100; static char s[maxlen]; if (x<0) { putchar('-'); x=-x;} if(!x){ putchar('0'); return; } int len=0; for(;x;x/=10) s[len++]=x % 10+'0'; for(int i=len-1;i>=0;--i) putchar(s[i]);}const int maxn=120000;char s[maxn];int nex[maxn][22];int st[maxn];int now[22];int a[maxn];int n;int get_num( char ch){if (ch=='e') return 0;if (ch=='a') return 1;if (ch=='s') return 2;if (ch=='y'); return 3;}void doit(int l,int r){int x=l;int nowlen=20;int ans=0;x=st[ l ];if ( (x>r)|| (x==0) ) { puts("0"); return ; }for (;;) { while ( ( nowlen>0 ) && ( ( ( nex[x][nowlen]==0 ) || ( nex[x][nowlen]>r ) ) ) ) nowlen--; if ( nowlen < 2 ) break; ans+=( 1<<( nowlen-2 ) ); x=nex[x][nowlen]; }int cnt=0;while ( (nex[x][0]<=r)&& (nex[x][0]!=0) ) { x=nex[x][0]; cnt++; }if (cnt==3) ans++;printf("%d\n",ans);}int main(){ scanf("%s",s); n=strlen(s); for (int i=0;i<n;i++) a[i+1]=get_num( s[i]); for (int i=n;i>=1;i--) { nex[i][0]=now[ (a[i]+1)%4 ]; now[ a[i] ]=i; st[ i ]=now[0]; } for (int i=1;i<=20;i++) for (int j=1;j<=n;j++) nex[ j ][ i ]=nex[ nex[ j ][ i-1] ] [ i-1 ]; int m; read(m); for (int i=1;i<=m;i++) { int l,r; read(l); read(r); int tot=0; doit( l , r); } return 0;}
阅读全文
0 0
- As Easy As Possible 倍增法
- bnuoj 52317 As Easy As Possible(预处理+倍增法)
- As Easy As Possible
- 2016弱校联盟十一专场10.5---As Easy As Possible(倍增)
- BNUOJ 52317 As Easy As possible
- as precise as possible
- As Fast As Possible
- as rigid as possible编译
- 弱校连萌 2016 国庆训练计划 10,5 Problem A. As Easy As Possible
- As-Rigid-As-Possible Surface Modeling
- Get Users Involved As Early As Possible
- As-Rigid-As-Possible Surface Modeling
- As-Conformal-As-Possible Surface Registration
- Codeforces700A As Fast As Possible 数学推理
- CF 700A As Fast As Possible
- as-conformal-as-possible discrete volumetric mapping
- codeforces 701 D. As Fast As Possible
- As easy as A+B
- 深度解析链表操作
- HDU-5072 Coprime(容斥原理,同色三角形)
- Java开发中的23种设计模式详解(转)
- 【多校训练】hdu 6166 Senior Pan 最短路径 Dijkstra
- codeforces738C
- As Easy As Possible 倍增法
- 关系的三类完整性约束
- JavaWeb开发之Maven工程(SSM框架)
- Python类实现动物种类的派生
- TFileStream用法
- C++内存管理之结构体内存释放
- JFinal解决IE浏览器下载问题
- Kali-Linux安装中文输入法
- 润乾V5如何实现第一次预览报表不展示数据