題目鏈接:https://www.luogu.org/problemnew/show/P1198
現在請求你維護一個數列,要求提供以下兩種操作:
注意:初始時數列是空的,沒有一個數。
分塊啊。
由於確定了最終數字不會超過
,所以就可以直接確定分成
個塊,使用計算器得
那就將一個塊設置成
就好了。
對於一個插入操作,判斷是否需要建立一個新的塊。然後將數據儲存進去。
對於一個查詢操作,按照樸素的分塊求法求
的最大值即可。
#include <cstdio> #include <algorithm> using namespace std; typedef long long ll; const int N=200010; const int T=448; int n,m,MOD,x,t,a[N],L[T],R[T],maxn[T],pos[N],ans; char c; int find_max(int l,int r) //暴力求l到r的最大值 { int Maxn=-2147483648; for (int i=l;i<=r;i++) Maxn=max(Maxn,a[i]); return Maxn; } int ask(int l,int r) { int q=pos[l],p=pos[r]; if (q==p) return ans=find_max(l,r); //直接暴力求 int Maxn=max(find_max(l,R[q]),find_max(L[p],r)); //兩邊暴力求 for (int i=q+1;i<p;i++) Maxn=max(Maxn,maxn[i]); return ans=Maxn; } int main() { scanf("%d%d",&m,&MOD); while (m--) { c=getchar(); while (c!='A'&&c!='Q') c=getchar(); scanf("%d",&x); if (c=='A') { a[++n]=(int)(((ll)x+(ll)ans)%MOD); //此處會炸int,切記用long long! if (n%T==1) //建立新塊 { t++; L[t]=R[t]=R[t-1]+1; } else R[t]++; pos[n]=t; maxn[t]=max(maxn[t],a[n]); } else printf("%d\n",ask(n-x+1,n)); } return 0; }