[线段树]校OJ-JSOI2008最大数
Posted zero_orez6
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[线段树]校OJ-JSOI2008最大数相关的知识,希望对你有一定的参考价值。
JSOI2008最大数
大意
给定n个数,每个数保证小于p,下面执行两个操作
- 添加:再当前序列末尾加上一个数
- 询问:输出序列后L位中的最大值
思路
因为每次询问是某一段范围的最大值,用动态开点的线段树写起来更优
code
#include<bits/stdc++.h>
using namespace std;
const int M=4e5;
int m,p,ans=0,num=0,root=0;
char c;
int a;
struct tree
{
int l,r,zhi;
#define l(o) t[o].l
#define r(o) t[o].r
#define zhi(o) t[o].zhi
}t[4*M];
int cnt;
void add(int &p,int bh,int l,int r,int d)
{
if(!p) p=++cnt;
if(l==r)
{
zhi(p)=d;
return;
}
int mid=(l+r)/2;
if(bh<=mid) add(l(p),bh,l,mid,d);
else add(r(p),bh,mid+1,r,d);
zhi(p)=max(zhi(l(p)),zhi(r(p)));
}
int ask(int p,int ll,int rr,int l,int r)
{
if(l>=ll&&r<=rr)
{
return zhi(p);
}
int mid=(l+r)/2;
int maxx=-1;
if(ll<=mid) maxx=ask(l(p),ll,rr,l,mid);
if(rr>mid) maxx=max(maxx,ask(r(p),ll,rr,mid+1,r));
return maxx;
}
int main()
{
scanf("%d%d",&m,&p);
for(int i=1;i<=m;i++)
{
scanf("%s%d",&c,&a);
if(c=='Q')
{
ans=ask(root,num-a+1,num,1,m);
printf("%d\\n",ans);
}
else
{
add(root,num+1,1,m,(ans%p+a%p)%p);
num++;
}
}
return 0;
}
以上是关于[线段树]校OJ-JSOI2008最大数的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ1012: [JSOI2008]最大数maxnumber [线段树]
[BZOJ1012][JSOI2008]最大数maxnumber 线段树