洛谷 P1198 [JSOI2008]最大数(线段树)

传送门


解题思路

单点修改区间查询最大值。
lazy标记都不需要。
总范围为读入的m的范围。
注意有负值。

AC代码

#include<cstdio>
#include<iostream>
#include<cstring>
#include<iomanip>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=2e5+5;
int n,now,cnt=1,lson[maxn*2],rson[maxn*2];
long long mod,last,d[maxn*2];
inline void pushup(int id){
	d[id]=max(d[lson[id]],d[rson[id]]);
}
inline void get(int id){
	if(lson[id]==0) lson[id]=++cnt;
	if(rson[id]==0) rson[id]=++cnt;
}
void insert(int id,int l,int r,int x,int v){	
	if(l==r){
		d[id]=v;
		return;
	}
	get(id);
	int mid=(l+r)/2;
	if(x<=mid) insert(lson[id],l,mid,x,v);
	else insert(rson[id],mid+1,r,x,v);
	pushup(id); 
}
long long query(int id,int l,int r,int x,int y){
	if(x<=l&&r<=y){
		return d[id];
	}
	get(id);
	int mid=(l+r)/2;
	long long res=-1e15;
	if(x<=mid) res=max(res,query(lson[id],l,mid,x,y));
	if(y>mid) res=max(res,query(rson[id],mid+1,r,x,y));
	return res;
}
int main(){
	ios::sync_with_stdio(false);
	cin>>n>>mod;
	for(int i=1;i<=n;i++){
		char c;
		long long x;
		cin>>c>>x;
		if(c=='A') insert(1,1,200000,++now,(last+x)%mod);
		else{
			cout<<(last=query(1,1,200000,now-x+1,now))<<endl;
		}
	}
    return 0;
}
posted @ 2021-09-15 10:29  尹昱钦  阅读(34)  评论(0编辑  收藏  举报