算法提高之最大数
-
核心思想:线段树
- 添加数
- 看作原本的数组有数(0) 现在将他修改成另一个值
- 询问后l个数的最大值
- query函数具体实现
- 添加数
-
#include <iostream>#include <cstring>#include <algorithm>using namespace std;const int N = 200010;typedef long long LL;int m,p;struct edge{int l,r;int v; //最大值}tr[N*4];void pushup(int u){//两子树的最大值的最大值tr[u].v = max(tr[u<<1].v,tr[u<<1 | 1].v);}void build(int u,int l,int r){tr[u] = {l,r};if(l == r) return; //如果是叶子节点int mid = l + r >> 1;build(u<<1,l,mid) , build(u<<1|1,mid+1,r);}int query(int u,int l,int r){//如果子树节点被区间全覆盖 说明子树节点足够小if(tr[u].l >= l && tr[u].r <= r) return tr[u].v;//子树节点不够小 需要细分int mid = tr[u].l + tr[u].r >> 1;int v=0;//如果l在左侧 取左子树if(l<=mid) v = query(u<<1,l,r);if(r>mid) v = max(v,query(u<<1|1,l,r));return v;}void modify(int u,int x,int v){//找到x的位置if(tr[u].l == x && tr[u].r == x) tr[u].v = v;else{int mid = tr[u].l + tr[u].r >> 1;//如果x较小 取左子树if(x <= mid) modify(u<<1,x,v);else modify(u<<1|1,x,v);//更新修改完后 要向上返回更新父节点值pushup(u);}}int main(){cin>>m>>p;int n=0,last=0;build(1,1,m);while(m--){char op[2];int t;cin>>op>>t;if(op[0] == 'A'){//改最后的数modify(1,n+1,((LL)last + t) % p);n ++;}else{//寻味n-t+1 - n这t个数的最大值last = query(1,n-t+1,n);cout<<last<<endl;}}}