I Hate It_hdu_1754(线段树).java

29 篇文章 0 订阅
7 篇文章 0 订阅

I Hate It

Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 27492    Accepted Submission(s): 10913


Problem Description
很多学校流行一种比较的习惯。老师们很喜欢询问,从某某到某某当中,分数最高的是多少。
这让很多学生很反感。

不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问。当然,老师有时候需要更新某位同学的成绩。
 

Input
本题目包含多组测试,请处理到文件结束。
在每个测试的第一行,有两个正整数 N 和 M ( 0<N<=200000,0<M<5000 ),分别代表学生的数目和操作的数目。
学生ID编号分别从1编到N。
第二行包含N个整数,代表这N个学生的初始成绩,其中第i个数代表ID为i的学生的成绩。
接下来有M行。每一行有一个字符 C (只取'Q'或'U') ,和两个正整数A,B。
当C为'Q'的时候,表示这是一条询问操作,它询问ID从A到B(包括A,B)的学生当中,成绩最高的是多少。
当C为'U'的时候,表示这是一条更新操作,要求把ID为A的学生的成绩更改为B。
 

Output
对于每一次询问操作,在一行里面输出最高成绩。
 

Sample Input
  
  
5 6 1 2 3 4 5 Q 1 5 U 3 6 Q 3 4 Q 4 5 U 2 9 Q 1 5
 

Sample Output
  
  
5 6 5 9
Hint
Huge input,the C function scanf() will work better than cin
 
import java.util.Scanner;
public class Main {//Time Limit Exceeded	1754	9000MS	29404K	1663 B	Java	zhangyi
	private static Node node[]=new Node[600000];
	public static void main(String[] args) {
		Scanner input=new Scanner(System.in);
		// Node node[]=new Node[600000];
		 /*for(int i=0; i<node.length; i++) {
			 node[i] = new Node();
		 }*/
		while(input.hasNext()){
			int n=input.nextInt();
			int m=input.nextInt();
			Init(1,n+1,1);
			//Init(1,n+1,1,node);
			for(int i=1;i<=n;i++){
				int t=input.nextInt();
				upData(i,t,1);
			}
			for(int i=1;i<=m;i++){
				String s=input.next();
				int a=input.nextInt();
				int b=input.nextInt();
				if(s.charAt(0)=='Q'){
					System.out.println(show(a,b+1,1));
				}
				else
					upData(a,b,1);
			}
		}
	}
	private static int show(int a, int b, int n) {
		if(a==node[n].L&&b==node[n].R)
			return node[n].max;
		if(node[n].L+1==node[n].R)
			return node[n].max;
		if(a<node[n].mid){
			//if(b<=node[n].mid)
			if(b<node[n].mid)
				return show(a,b,2*n);
			else
				return Math.max(show(a,node[n].mid,2*n), show(node[n].mid,b,2*n+1));
		}
		else{
			return show(a,b,2*n+1);
		}
	}
	private static void upData(int i, int t, int n) {
		if(t>node[n].max)
			node[n].max=t;
		if(node[n].L+1==node[n].R)
			return;
		if(i<node[n].mid){
			upData(i,t,n*2);
		}
		else{
			upData(i,t,n*2+1);
		}
	}
	private static void Init(int l, int r, int n) {
		node[n]=new Node(l,r,(l+r)/2,-1);
		if(l+1==r)
			return ;
		Init(l,(l+r)/2,n*2);
		Init((l+r)/2,r,n*2+1);
	}
}

class Node{
	int L,R,mid,max;
	Node(int L,int R,int mid,int max){
		this.L=L;
		this.R=R;
		this.mid=mid;
		this.max=max;
	}
	Node(){};
}


import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Main {//超内存
	private static  Node node[]=new Node[550000];
	public static void main(String[] args) {
		BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
		try {
			while(true){
				String s1=bf.readLine();
				if(s1.length()==0)
					break;
				String s2[]=s1.split(" ");
				int n=Integer.parseInt(s2[0]);
				int m=Integer.parseInt(s2[1]);
				Init(1,n+1,1);
				s1=bf.readLine();
				String s3[]=s1.split(" ");
				for(int i=1;i<=n;i++){
					upData(i,Integer.parseInt(s3[i-1]),1);
				}
				for(int i=1;i<=m;i++){
					s1=bf.readLine();
					String s4[]=s1.split(" ");
					/*String s=input.next();
					int a=input.nextInt();
					int b=input.nextInt();*/
					if(s4[0].charAt(0)=='Q'){
						System.out.println(show(Integer.parseInt(s4[1]),Integer.parseInt(s4[2])+1,1));
					}
					else
						upData(Integer.parseInt(s4[1]),Integer.parseInt(s4[2]),1);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	private static int show(int a, int b, int n) {
		if(a==node[n].L&&b==node[n].R)
			return node[n].max;
		if(a<node[n].mid){
			if(b<=node[n].mid)
				return show(a,b,2*n);
			else
				return Math.max(show(a,node[n].mid,2*n), show(node[n].mid,b,2*n+1));
		}
		else{
			return show(a,b,2*n+1);
		}
	}
	private static void upData(int i, int t, int n) {
		if(t>node[n].max)
			node[n].max=t;
		if(node[n].L+1==node[n].R)
			return;
		if(i<node[n].mid){
			upData(i,t,n*2);
		}
		else{
			upData(i,t,n*2+1);
		}
	}
	private static void Init(int l, int r, int n) {
		node[n]=new Node(l,r,(l+r)/2,-1);
		if(l+1==r)
			return ;
		Init(l,(l+r)/2,n*2);
		Init((l+r)/2,r,n*2+1);
	}
}

class Node{
	int L,R,mid,max;
	Node(int L,int R,int mid,int max){
		this.L=L;
		this.R=R;
		this.mid=mid;
		this.max=max;
	}
	Node(){};
}

/*
8912671	2013-08-12 11:05:30	Accepted	1754	2593MS	8600K	1748 B	G++	zhangyi
*/

#include <iostream>
using namespace std;
struct Node
{
    int l,r,mid,max;
}node[600000];

int max(int a,int b)
{
    return a>b?a:b;
}

void inint(int a,int b,int n)
{
    node[n].l=a;
    node[n].max=-1;
    node[n].r=b;
    node[n].mid=(a+b)/2;
    
    if(a+1==b)
    return;
    inint(a,(a+b)/2,n*2);
    inint((a+b)/2,b,2*n+1);
}

void update(int pos,int value,int n)
{
    if(value>node[n].max)
    node[n].max=value;
    if((node[n].l+1)==node[n].r)
    return;
    if(pos<node[n].mid)
    {
        update(pos,value,2*n);
    }
    if(pos>=node[n].mid)
    {
        update(pos,value,2*n+1);
    }
}

int query(int a,int b,int n)
{
    if(node[n].l==a && node[n].r==b)
    return node[n].max;
    if(a<node[n].mid)
    {
        if(b<=node[n].mid)
        {
            return query(a,b,2*n);
        }
        else
        {
            return max(query(a,node[n].mid,2*n),query(node[n].mid,b,2*n+1));
        }
    }
    else
    {
        return query(a,b,2*n+1);
    }
}
    
int main()
{
     int n,m,t,a,b,i;
     char ch;
     while(cin >>n>>m)
     {
            inint(1,n+1,1);
            //cout <<"fdslafj"<<endl;
            for(i=1;i<=n;i++)
            {
                scanf("%d",&t);
                update(i,t,1);
                //cout <<node[i].max<<endl;
            }            
            for(i=1;i<=m;i++)
            {
                getchar();
                cin >>ch;
                cin >>a>>b;
                if(ch=='Q')
                cout <<query(a,b+1,1)<<endl;//注意是b+1而不是b。因为线段树是一个左开右闭的的区间。
                else
                update(a,b,1);
            }
    }
    return 0;
}


java,要么超时,要么超内存,要么直接WA,java伤不起;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值