BZOJ 1012: [JSOI2008]最大数maxnumber

线段树水题,一个节点一个节点的建,保存上一次结果,以及序列长度即可。

http://www.zybbs.org/JudgeOnline/problem.php?id=1012

#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <string>
#include <algorithm>
#define MID(x,y) ( ( x + y ) >> 1 )
#define L(x) ( x << 1 )
#define R(x) ( x << 1 | 1 )
#define BUG puts("here!!!")

using namespace std;

const int MAX = 200010;
int MOD,P;
struct Tnode{				// 一维线段树 
    int l,r,val;
  	long long max;
    int len() { return r - l;}
    int mid() { return MID(l,r);}
    bool in(int ll,int rr) { return l >= ll && r <= rr; }
    void lr(int ll,int rr){ l = ll; r = rr;}
};
Tnode node[MAX<<2];
void init()
{
	memset(node,0,sizeof(node));
}
void Build(int t,int l,int r)
{
	node[t].lr(l,r);
	if( node[t].len() == 1 ) return ;
	int mid = MID(l,r);
	Build(L(t),l,mid);
	Build(R(t),mid,r);
}

void Updata(int t,int l,int r,int val)
{
	if( node[t].in(l,r) )
	{
		node[t].max += val;
		P = node[t].max;
		return ;
	}
	if( node[t].len() == 1 ) return ;
	int mid = node[t].mid();
	if( l < mid ) Updata(L(t),l,r,val);
	if( r > mid ) Updata(R(t),l,r,val);
	node[t].max = max(node[L(t)].max, node[R(t)].max);
}

int Query(int t,int l,int r)
{
	if( node[t].in(l,r) )	return node[t].max;
	if( node[t].len() == 1 ) return 0;
	int mid = node[t].mid();
	int ans = 0;
	if( l < mid ) ans = max(ans,Query(L(t),l,r));
	if( r > mid ) ans = max(ans,Query(R(t),l,r));
	return ans;
}

int main()
{
	int m,x;
	char ch[5];
	while( ~scanf("%d%d",&m,&MOD) )
	{
		init();
		Build(1,0,m);
		int t = 0,len = 0;
		while( m-- )
		{
			scanf("%s%d",ch,&x);
			switch(ch[0])
			{
				case 'A' :Updata(1,len,len+1,(t+x)%MOD); len++; break;
				case 'Q' : int ans = Query(1,len-x,len); printf("%d\n",ans); t = ans;
			}
		}
	}

return 0;
}


你可能感兴趣的:(BZOJ 1012: [JSOI2008]最大数maxnumber)