bzoj千題計劃312:bzoj2119: 股市的預測(字尾陣列+st表)
#include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define N 50001 #define M 15 typedef long long LL; int n,m,tot; int b[N]; int a1[N],a2[N]; int has[N]; int sa1[2][N],rk1[2][N],h1[N];int sa2[2][N],rk2[2][N],h2[N]; int p1,q1=1; int p2,q2=1; int v[N]; int k; int st1[N][M+1],st2[N][M+1]; void read(int &x) { x=0; int f=1; char c=getchar(); while(!isdigit(c)) { if(c=='-') f=-1; c=getchar(); } while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); } x*=f; }void mul(int *sa,int *rk,int*SA,int *RK) { for(int i=1;i<=n;++i) v[rk[sa[i]]]=i; for(int i=n;i;--i) if(sa[i]>k) SA[v[rk[sa[i]-k]]--]=sa[i]-k; for(int i=n-k+1;i<=n;++i) SA[v[rk[i]]--]=i; for(int i=1;i<=n;++i) RK[SA[i]]=RK[SA[i-1]]+(rk[SA[i]]!=rk[SA[i-1]] || rk[SA[i]+k]!=rk[SA[i-1]+k]); } void presa(int &p,int &q,int a[N],int sa[2][N],int rk[2][N]) { memset(v,0,sizeof(v)); for(int i=1;i<=n;++i) v[a[i]]++; for(int i=1;i<=tot;++i) v[i]+=v[i-1]; for(int i=1;i<=n;++i) sa[p][v[a[i]]--]=i; for(int i=1;i<=n;++i) rk[p][sa[p][i]]=rk[p][sa[p][i-1]]+(a[sa[p][i]]!=a[sa[p][i-1]]); for(k=1;k<n;k<<=1,swap(p,q)) mul(sa[p],rk[p],sa[q],rk[q]); } void get_height(int *a,int *h,int *sa,int *rk) { int k=0,j; for(int i=1;i<=n;++i) { j=sa[rk[i]-1]; while(a[i+k]==a[j+k]) k++; h[rk[i]]=k; if(k) k--; } } void prest(int h[N],int st[N][M+1]) { for(int i=2;i<=n;++i) st[i][0]=h[i]; for(int i=1,k=2;i<=M;++i,k<<=1) for(int j=2;j+k-1<=n;++j) st[j][i]=min(st[j][i-1],st[j+k/2][i-1]); } int get(int st[N][M+1],int i,int j,int *rk) { i=rk[i]; j=rk[j]; if(i>j) swap(i,j); i++; int l=1.0*log(j-i+1)/log(2); return min(st[i][l],st[j-(1<<l)+1][l]); } void solve() { LL ans=0; int j; int lcp,lcs,sum; for(int len=1;len<n;++len) for(int i=1;i+len+m<=n;i+=len) { j=i+len+m; lcs=get(st1,i,j,rk1[p1]); if(lcs>len) lcs=len; lcp=get(st2,n-j+1,n-i+1,rk2[p2]); if(lcp>len) lcp=len; sum=lcp+lcs-1; if(sum>=len) { ans+=sum-len+1; // printf("%d %d %d %d\n",i,j,len,sum-len+1); } } cout<<ans; } int main() { freopen("nt2011_stock.in","r",stdin); freopen("nt2011_stock.out","w",stdout); read(n); read(m); for(int i=1;i<=n;++i) read(b[i]); for(int i=1;i<n;++i) a1[i]=b[i+1]-b[i],has[i]=a1[i]; n--; sort(has+1,has+n+1); tot=unique(has+1,has+n+1)-has-1; for(int i=1;i<=n;++i) a1[i]=lower_bound(has+1,has+tot+1,a1[i])-has; for(int i=1;i<=n;++i) a2[n-i+1]=a1[i]; presa(p1,q1,a1,sa1,rk1); get_height(a1,h1,sa1[p1],rk1[p1]); presa(p2,q2,a2,sa2,rk2); get_height(a2,h2,sa2[p2],rk2[p2]); prest(h1,st1); prest(h2,st2); solve(); }
相關推薦
bzoj千題計劃314:bzoj3238: [Ahoi2013]差異(字尾陣列+st表+單調棧)
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define N 500001 int n
bzoj千題計劃312:bzoj2119: 股市的預測(字尾陣列+st表)
#include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #d
bzoj千題計劃319:bzoj2865: 字串識別(字尾自動機 + 線段樹)
#include<map> #include<cstdio> #include<cstring> #include<algorithm> #define N 500001 using namespace std; char s[
bzoj千題計劃308:bzoj4589: Hard Nim(倍增FWT+生成函式)
#include<cstdio> #include<cstring> using namespace std; #define N 50001 const int mod=1e9+7; const int M=1<<16; int inv
bzoj千題計劃311:bzoj5017: [Snoi2017]炸彈(線段樹優化tarjan構圖)
#include<cstdio> #include<vector> #include<iostream> #include<algorithm> using namespace std; const int mod=1e9+7;
bzoj千題計劃315:bzoj3172: [Tjoi2013]單詞(AC自動機)
#include<queue> #include<cstdio> #include<cstring> using namespace std; #define N 2000001 using namespace std; int pos[20
bzoj千題計劃310:bzoj5285: [Hnoi2018]尋寶遊戲(思維題+雜湊)
#include<cstdio> #include<algorithm> #define N 5001 using namespace std; const int mod=1e9+7; int bit[N]; char s[N]; int has
bzoj千題計劃316:bzoj3173: [Tjoi2013]最長上升子序列(二分+樹狀陣列)
#include<cstdio> #include<iostream> #include<algorithm> using namespace std; #define N 100001 #define lowbit(x) x&-x
bzoj千題計劃309:bzoj4332: JSOI2012 分零食(分治+FFT)
#include<cmath> #include<cstdio> #include<algorithm> using namespace std; const int M=1<<17; #define N 10001 int m,
bzoj千題計劃321:bzoj5251: [2018多省省隊聯測]劈配(網路流 + 二分)
#include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #d
bzoj千題計劃317:bzoj4650: [Noi2016]優秀的拆分(字尾陣列+差分)
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define N 30002 using namespace std; int n;
bzoj千題計劃318:bzoj1396: 識別子串(字尾自動機 + 線段樹)
#include<cstdio> #include<cstring> #include<algorithm> #define N 100001 using namespace std; char s[N]; int ch[N<&
bzoj千題計劃323:bzoj1951: [Sdoi2010]古代豬文(Lucas+CRT+尤拉定理)
#include<cmath> #include<cstdio> #include<iostream> using namespace std; const int mod=999911659; const int phi=mod-1; typ
bzoj千題計劃322:bzoj2561: 最小生成樹(最小割)
#include<cstdio> #include<queue> #include<cstring> #include<iostream> #include<algorithm> using namespace std;
bzoj千題計劃324:bzoj5249: [2018多省省隊聯測]IIIDX(線段樹)
#include<cmath> #include<cstdio> #include<iostream> #include<algorithm> using namespace std; #define N 500001 int d[N
bzoj千題計劃313:bzoj3879: SvT(字尾陣列+st表+單調棧)
#include<cstdio> #include<iostream> #include<algorithm> using namespace std; #define N 500001 #define M 3000001 int n,m,mm;
bzoj千題計劃320:bzoj4939: [Ynoi2016]掉進兔子洞(莫隊 + bitset)
#include<cmath> #include<cstdio> #include<bitset> #include<cstring> #include<iostream> #include<algorithm> us
BZOJ 2119 股市的預測(字尾陣列)
首先要差分+離散化。 然後就是求形如ABA的串有多少,其中B的長度確定為k。 我們用到了設定關鍵點的思想。我們列舉A的長度L。然後在\(1,1+L,1+L*2,1+L*3。。。\)設定關鍵點。然後我們列舉這些關鍵點,試圖求出跨過這個關鍵點的長度為L的在B左邊的A有多少個。 可以證明這樣可以做到不重不漏,因為A
BZOJ[4516][Sdoi2016]生成魔咒 字尾陣列+ST表+線段樹
首先感謝Sinogi大佬的耐心講解及程式碼 題意就是每次加一個字元,統計本質不同的子串數量 正向新增字元不好做,考慮反著刪字元 在正常情況下,刪掉位置ii的一個字元會減少ii個子串(∑j<=ij=1sj...i∑j=1j<=isj...i)
編程題#3:奇偶排序(二)
log cnblogs 保存 比較 如果 () return names space #include <iostream> using namespace std; int main() { int n, a[1000]; // 一共n個數,n不超過