720--詞典中最長的單詞(字典樹)
阿新 • • 發佈:2022-03-06
題面傳送門
題目中怎麼不說明這個可以取空區間啊害我調半天。
這個重複的算一次就容易想到區間數顏色的相關套路,就是每個點記錄前面最近的點。
離線詢問然後掃描線,記錄線段樹上每個位置的值為到當前點的區間的和,那麼需要做的就是兩種操作:
將上一個這個數的出現位置+1到現在的位置都加上一個數。
查詢區間歷史最值。
歷史最值有基本套路,新加一個權值\(F_i\)表示\(i\)位置的歷史最值,那麼每次掃描完一個數以後就對於全序列讓\(F_i=\max(F_i,A_i)\)
這個維護一個標記,再配合一個位移標記就可以和加法相容了。
時間複雜度線段樹的\(O(n\log n)\)
code:
#include<bits/stdc++.h> #define I inline #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b)) #define abs(x) ((x)>0?(x):-(x)) #define re register #define RI re int #define ll long long #define db double #define lb long db #define N (100000+5) #define M (1000000+5) #define mod 1000000007 #define Mod (mod-1) #define eps (1e-9) #define U unsigned int #define it iterator #define Gc() getchar() #define Me(x,y) memset(x,y,sizeof(x)) #define Mc(x,y) memcpy(x,y,sizeof(x)) #define d(x,y) (n*(x-1)+(y)) #define R(n) (rand()*rand()%(n)+1) #define Pc(x) putchar(x) #define LB lower_bound #define UB upper_bound #define PB push_back using namespace std;const ll INF=1e18; int n,m,k,x,y;ll Ans[N],A[N];map<ll,int> F;struct Ques{int x,id;};vector<Ques> Q[N+5]; namespace Tree{ #define ls now<<1 #define rs now<<1|1 int Fl[N+5<<2];ll W[N+5<<2],G[N+5<<2],F[N+5<<2],H[N+5<<2];I void Up(int now){F[now]=max(F[ls],F[rs]);G[now]=max(G[ls],G[rs]);} I void PL(int now,ll w){Fl[now]?(W[now]=max(W[now],w)):(Fl[now]=1,W[now]=w);G[now]=max(G[now],F[now]+W[now]);}I void PH(int now,ll w){H[now]+=w;F[now]+=w;Fl[now]&&(W[now]-=w);} I void P(int now){H[now]&&(PH(ls,H[now]),PH(rs,H[now]),H[now]=0);Fl[now]&&(PL(ls,W[now]),PL(rs,W[now]),Fl[now]=W[now]=0);} I ll Qry(int x,int y,int l=1,int r=n,int now=1){if(x<=l&&r<=y) return G[now];P(now);int m=l+r>>1;ll F1=-INF,F2=-INF;x<=m&&(F1=Qry(x,y,l,m,ls));y>m&&(F2=Qry(x,y,m+1,r,rs));return max(F1,F2);} I void Ins(int x,int y,ll w,int l=1,int r=n,int now=1){if(x<=l&&r<=y) return PH(now,w);int m=l+r>>1;P(now);x<=m&&(Ins(x,y,w,l,m,ls),0);y>m&&(Ins(x,y,w,m+1,r,rs),0);Up(now);} I void Add(int x,int y,int l=1,int r=n,int now=1){if(x<=l&&r<=y) return PL(now,0);int m=l+r>>1;P(now);x<=m&&(Add(x,y,l,m,ls),0);y>m&&(Add(x,y,m+1,r,rs),0);Up(now);} } int main(){ freopen("1.in","r",stdin); RI i;scanf("%d",&n);for(i=1;i<=n;i++) scanf("%lld",&A[i]);scanf("%d",&m);for(i=1;i<=m;i++) scanf("%d%d",&x,&y),Q[y].PB((Ques){x,i}); for(i=1;i<=n;i++) {Tree::Ins(F[A[i]]+1,i,A[i]);F[A[i]]=i;Tree::Add(1,n);for(Ques d:Q[i]) Ans[d.id]=Tree::Qry(d.x,i);}for(i=1;i<=m;i++) printf("%lld\n",Ans[i]); }