We'll call a non-empty string S[ p1p2... pk] = sp1sp2... spk(1 ≤ p1 < p2 < ... < pk ≤ | s|) a subsequence of string s = s1s2... s |s|.
String x = x1x2... x |x| is lexicographically larger than string y = y1y2... y |y|, if either | x| > | y| and x1 = y1, x2 = y2, ... , x |y| = y |y|, or exists such number r ( r < | x|, r < | y|), that x1 = y1, x2 = y2, ... , xr = yr and xr + 1 > yr + 1. Characters in lines are compared like their ASCII codes.
The hash value for string s of length n is .
abeced 2 1 3 1 6 kjihgfedcba 1 1 11
101 514298749 888634539
子序列是指:“abeced”的最大子序列为eed。
2traits:
1、每个区间的最优序列首字母一定是【该区间内最大值的首个出现位置】
2、对于每个区间[l,r]内的最优子序列,r这个点一定会被选进去
3、两个不同的点a,b,且a>b,往前的最优祖先一定一样
#include<bits/stdc++.h>
#define ll long long
#define inf 0x7fffffff
#define mod 1000000007
#define lowbit(x) (x) & (-x)
using namespace std;
int pre[1000005];
int len[1000005];
ll sum[1000005];
ll g[1000005];
int id[30];
int w[1000005];
int c2[1000005];
char x[1000005];
int n;
const int MAXN = 1000005;
int dp[MAXN][22];
void makermq(int n,int b[])
{
int i,j;
for(i=1;i<=n;i++)
dp[i][0]=b[i];
for(j=1;(1<<j)<=n;j++)
for(i=1;i+(1<<j)-1<=n;i++)
dp[i][j]=min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
}
int rmq(int s,int v)
{
int k=(int)(log((v-s+1)*1.0)/log(2.0));
return min(dp[s][k],dp[v-(1<<k)+1][k]);
}
void makeRmqIndex(int n,int b[]) //返回最大值对应的下标
{
int i,j;
for(i=1;i<=n;i++)
dp[i][0]=i;
for(j=1;(1<<j)<=n;j++)
for(i=1;i+(1<<j)-1<=n;i++)
dp[i][j]=b[dp[i][j-1]] >= b[dp[i+(1<<(j-1))][j-1]]? dp[i][j-1]:dp[i+(1<<(j-1))][j-1];
}
int rmqIndex(int s,int v,int b[])
{
int k=(int)(log((v-s+1)*1.0)/log(2.0));
return b[dp[s][k]]>=b[dp[v-(1<<k)+1][k]]? dp[s][k]:dp[v-(1<<k)+1][k];
}
int main(){
g[0]=1;
for(int i=1;i<=1000000;++i) g[i]=g[i-1]*1000007%mod;
while(scanf("%s",x+1)!=EOF){
memset(id,0,sizeof(id));
n=strlen(x+1);
for(int i=1;i<=n;++i){
w[i]=x[i]-'a'+1;
int maxx=0;
for(int j=x[i]-'a';j<26;++j){
maxx=max(maxx,id[j]);
}
pre[i]=maxx;
len[i]=len[maxx]+1;
id[x[i]-'a']=i;
sum[i]=(sum[pre[i]]*1000007+x[i])%mod;
}
makeRmqIndex(n,w);
int q;
scanf("%d",&q);
while(q--){
int a,b;
scanf("%d%d",&a,&b);
// cout<<rmqIndex(a,b,w)<<endl;
int ip=rmqIndex(a,b,w);
printf("%lld\n",((sum[b]-sum[pre[ip]]*g[len[b]-len[pre[ip]]])%mod+mod)%mod);
}
}
}