原題鏈接:https://www.lydsy.com/JudgeOnline/problem.php?id=1012
下面是題解。
要求維護一個數列,支持查詢和插入操作。裸的線段樹模板。
由於一開始數列是空的,不需要線段樹的初始化,直接進行插入操作。
讀入部分:
for(int i=1;i<=m;i++){
read();
if(tmp=='A'){
size++;
add(1,m,(o+t)%d,1);
}
if(tmp=='Q'){
t=q(1,m,o,1);
printf("%d\n",t);
}
}
第一個功能:輸入一個n,要求在尾部插入(a+t)%d。
void add(int l,int r,int n,int rt)
{
if(l==r){
tree[rt]=n;
return ;
}
int mid=(l+r)/2;
tree[rt]=max(tree[rt],n);
if(size>=mid+1)add(mid+1,r,n,rt<<1|1);
else add(l,mid,n,rt<<1);
return ;
}
第二個功能:輸入一個n,要求查詢[size-n+1,size]的最大值
int q(int l,int r,int n,int rt)
{
if(l>=size-n+1&&r<=size){
return tree[rt];
}
int mid=(l+r)/2,ans=-10000;
if(mid>=size-n+1)ans=max(ans,q(l,mid,n,rt<<1));
if(mid+1<=size)ans=max(ans,q(mid+1,r,n,rt<<1|1));
return ans;
}
題目是很簡單。。不知道爲什麼一開始用cin超時了,後來加了個快讀玄學優化就過了。
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int t=0,size=0,m,d,o;
char tmp;
int tree[800009];
void add(int l,int r,int n,int rt);
int q(int l,int r,int n,int rt);
void read();
int main()
{
char c;
while((c=getchar())!=' ')m=m*10+(c-'0');
while((c=getchar())!='\n')d=d*10+(c-'0');
for(int i=1;i<=m;i++){
read();
if(tmp=='A'){
size++;
add(1,m,(o+t)%d,1);
}
if(tmp=='Q'){
t=q(1,m,o,1);
printf("%d\n",t);
}
}
return 0;
}
void add(int l,int r,int n,int rt)
{
if(l==r){
tree[rt]=n;
return ;
}
int mid=(l+r)/2;
tree[rt]=max(tree[rt],n);
if(size>=mid+1)add(mid+1,r,n,rt<<1|1);
else add(l,mid,n,rt<<1);
return ;
}
int q(int l,int r,int n,int rt)
{
if(l>=size-n+1&&r<=size){
return tree[rt];
}
int mid=(l+r)/2,ans=-10000;
if(mid>=size-n+1)ans=max(ans,q(l,mid,n,rt<<1));
if(mid+1<=size)ans=max(ans,q(mid+1,r,n,rt<<1|1));
return ans;
}
void read()
{
tmp=getchar();
while(tmp!='A'&&tmp!='Q')tmp=getchar();
getchar();
char c;
o=0;
while((c=getchar())!='\n'){
o=o*10+(c-'0');
}
}