洛谷3732:[HAOI2017]供給側改革——題解

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

Anihc國提升社會生產力水平.落實好以人民爲中心的發展思想。決定進行供給側結構性改革。ios

爲了提升供給品質.你調查了某個產業近來n個時期的供求關係平衡狀況.每一個時期的狀況都用0或1中的一個數字來表示.因而這就是—個長度爲n的01字符串S。爲了更好的瞭解這一些數據.你須要解決一些詢問.咱們令data(l,r)表示:在字符串S中.起始位置在[l,r]之間的這些後綴之中,具備最長公共前綴的兩個後綴的最長公共前綴的長度。git

對於每個詢問L,R.求sigma(data(i,R))。數組

因爲你其實根本沒有時間調查,因此這些數據都是亂編的,即串S中的每一位都是在0和1之間隨機產生的。spa

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

最後一句話很皮,因而咱們思考下發現公共前綴必定很短,連(看)猜(題)帶(解)蒙大概是40吧。blog

因而咱們把詢問離線,按照$r$排序,從左到右掃一遍$i$,將以$i$爲首的40位字符加入到trie樹中,以此維護$pos[k]$表示最小的區間$[pos[k],i]$,使得$data(pos[k],i)=k$。排序

(仍是很好維護的,若是不知道怎麼維護能夠看參考也能夠直接看代碼。)字符串

爲何咱們構造了$pos$數組呢?實際上是由於$data$的單調不增性。get

由此咱們發現$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/+

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

相關文章
相關標籤/搜索