洛谷3732:[HAOI2017]供给侧改革——题解

https://www.luogu.org/problemnew/show/P3732

Anihc国提高社会生产力水平.落实好以人民为中心的发展思想。决定进行供给侧结构性改革。

为了提高供给品质.你调查了某个产业近来n个时期的供求关系平衡情况.每个时期的情况都用0或1中的一个数字来表示.于是这就是—个长度为n的01字符串S。为了更好的了解这一些数据.你需要解决一些询问.我们令data(l,r)表示:在字符串S中.起始位置在[l,r]之间的这些后缀之中,具有最长公共前缀的两个后缀的最长公共前缀的长度。

对于每一个询问L,R.求sigma(data(i,R))。

由于你其实根本没有时间调查,所以这些数据都是乱编的,即串S中的每一位都是在0和1之间随机产生的。

参考:https://msy.blog.luogu.org/solution-p3732

最后一句话很皮,于是我们思考下发现公共前缀一定很短,连(看)猜(题)带(解)蒙大概是40吧。

于是我们把询问离线,按照$r$排序,从左到右扫一遍$i$,将以$i$为首的40位字符加入到trie树中,以此维护$pos[k]$表示最小的区间$[pos[k],i]$,使得$data(pos[k],i)=k$。

(还是很好维护的,如果不知道怎么维护可以看参考也可以直接看代码。)

为什么我们构造了$pos$数组呢?其实是因为$data$的单调不增性。

由此我们发现$data(pos[k+1]+1,i)$到$data(pos[k],i)$都是$k$。

答案就呼之欲出了。

#include<queue>
#include<cmath>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=1e5+5;
inline int read(){
    int X=0,w=0;char ch=0;
    while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
    while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    return w?-X:X;
}
struct node{
    int a[2],ed;
}tr[N*40];
struct data{
    int l,r,id;
}d[N];
char s[N];
int n,q,tot,pos[50];
ll ans[N];
inline bool cmp(data a,data b){
    return a.r<b.r;
}
void insert(int st){
    int now=0;
    for(int i=st;i<=min(n,st+39);i++){
        int w=s[i]-'0';
        if(!tr[now].a[w])tr[now].a[w]=++tot;
        now=tr[now].a[w];
        if(tr[now].ed)
            pos[i-st+1]=max(pos[i-st+1],tr[now].ed-i+st);
        tr[now].ed=i;
    }
}
int main(){
    n=read(),q=read();
    scanf("%s",s+1);
    for(int i=1;i<=q;i++){
        d[i].l=read(),d[i].r=read();
        d[i].id=i;
    }
    sort(d+1,d+q+1,cmp);
    for(int i=1,j=1;i<=n;i++){
        insert(i);
        while(j<=q&&d[j].r==i){
            for(int k=1;k<=40;k++){
                if(pos[k]>=d[j].l){
                    ans[d[j].id]+=(ll)k*(pos[k]-max(pos[k+1],d[j].l-1));
                }else break;
            }
            j++;
        }
    }
    for(int i=1;i<=q;i++)printf("%lld\n",ans[i]);
    return 0;
}

+++++++++++++++++++++++++++++++++++++++++++

 +本文作者:luyouqi233。               +

 +欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

posted @ 2018-06-25 22:31  luyouqi233  阅读(525)  评论(2编辑  收藏  举报