[bzoj]1012: [JSOI2008]最大數maxnumber

原題鏈接: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');
	}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章