题目描述
Anihc国提高社会生产力水平.落实好以人民为中心的发展思想。决定进行供给侧结构性改革。
为了提高供给品质.你调查了某个产业近来n个时期的供求关系平衡情况.每个时期的情况都用0或1中的一个数字来表示.于是这就是—个长度为n的01字符串S。为了更好的了解这一些数据.你需要解决一些询问.我们令data(l,r)表示:在字符串S中.起始位置在[l,r]之间的这些后缀之中,具有最长公共前缀的两个后缀的最长公共前缀的长度。
对于每一个询问L,R.求
a n s = ∑ L ≤ i < R d a t a ( i , R ) ans = \sum_{L\le i < R} data(i,R) ans=∑L≤i<Rdata(i,R)
由于你其实根本没有时间调查,所以这些数据都是乱编的,即串S中的每一位都是在0和1之间随机产生的。
输入输出格式
输入格式:
第一行2个整数n,Q,表示字符串的长度,以及询问个数
接下来一行长度为n的一个01串S
接下来Q行,每行2个整数L,R.一个询问L.R
输出格式:
共Q行.每行一个整数.表示对应询问的答案。
s
o
l
u
t
i
o
n
solution
solution:
把所有询问按照
r
r
r排序(
l
l
l也行)
按照起始位置的顺序插入
t
r
i
e
trie
trie树,同时更新某个长度最后一次出现的最远值
每次询问就从大到小扫一遍数组就行了
#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(int i = j;i <= k;++i)
#define repp(i,j,k) for(int i = j;i >= k;--i)
#define rept(i,x) for(int i = linkk[x],y = e[i].y;i;i = e[i].n,y = e[i].y)
#define P pair<int,int>
#define Pil pair<int,ll>
#define Pli pair<ll,int>
#define Pll pair<ll,ll>
#define pb push_back
#define pc putchar
#define mp make_pair
#define file(k) memset(k,0,sizeof(k))
#define ll long long
#define fr first
#define se second
int rd()
{
int num = 0;char c = getchar();bool flag = true;
while(c < '0'||c > '9') {if(c == '-') flag = false;c = getchar();}
while(c >= '0' && c <= '9') num = num*10+c-48,c = getchar();
if(flag) return num;else return -num;
}
int n,Q,tot;
int ch[6001000][2],rt,num[101000];
int ans[101000];
P f[6001000];
char s[101000];
vector<P>pl[101000];
struct data{int l,r,id;}q[101000];
bool mycmp(data x,data y){return x.r < y.r || (x.r==y.r && x.l < y.l);}
inline int max(int a,int b){return a>b?a:b;}
inline int min(int a,int b){return a<b?a:b;}
void update(int root,int id,int len)
{
if(f[root].fr == 0) f[root].fr = id;
else if(f[root].se == 0) f[root].se = id;
else f[root].fr = f[root].se,f[root].se = id;
if(f[root].fr && f[root].se)
num[len] = max(num[len],f[root].fr);
}
void insert(int i,int j)
{
int now = rt;
rep(x,i,j)
{
if(!ch[now][s[x]-'0']) ch[now][s[x]-'0'] = ++tot;
now = ch[now][s[x]-'0'];
}
update(now,i,j-i+1);
}
void calc(int r)
{
rep(x,0,(int)pl[r].size()-1)
{
int l = pl[r][x].fr,id = pl[r][x].se;
int i = l,now = 0;
repp(j,50,1)
if(num[j] >= i) now += j*(num[j]-i+1),i = num[j]+1;
ans[id] = now;
}
}
int main()
{
n = rd();Q = rd();rt = ++tot;
scanf("%s",s+1);
rep(i,1,Q) q[i].l = rd(),q[i].r = rd(),q[i].id = i;
sort(q+1,q+Q+1,mycmp);
rep(i,1,Q) pl[q[i].r].pb(mp(q[i].l,q[i].id));
rep(i,1,n)
{
rep(j,i,min(i+50-1,n)) insert(i,j);
calc(i);
}
rep(i,1,Q) printf("%d\n",ans[i]);
return 0;
}