「已注销」 2015-01-21 02:56 采纳率: 100%
浏览 1981

操作格子蓝桥杯java线段树也超限怎么办

如题:
问题描述
有n个格子,从左到右放成一排,编号为1-n。

共有m次操作,有3种操作类型:

1.修改一个格子的权值,

2.求连续一段格子权值和,

3.求连续一段格子的最大值。

对于每个2、3操作输出你所求出的结果。

输入格式
第一行2个整数n,m。

接下来一行n个整数表示n个格子的初始权值。

接下来m行,每行3个整数p,x,y,p表示操作类型,p=1时表示修改格子x的权值为y,p=2时表示求区间[x,y]内格子权值和,p=3时表示求区间[x,y]内格子最大的权值。

输出格式
有若干行,行数等于p=2或3的操作总数。

每行1个整数,对应了每个p=2或3操作的结果。

样例输入
4 3
1 2 3 4
2 1 3
1 4 3
3 1 4
样例输出
6
3
数据规模与约定
对于20%的数据n <= 100,m <= 200。

对于50%的数据n <= 5000,m <= 5000。

对于100%的数据1 <= n <= 100000,m <= 100000,0 <= 格子权值 <= 10000。

我用的java,用线段树写的,结果还是时间超限,高手求解
代码如下:

/**

  • 线段树,操作格子
  • @author Administrator * */ class Node { int max,sum; int left,right; Node lNode,rNode; //构造方法 Node() { max = 0; sum = 0; lNode = null; rNode = null; }

}
public class Tree {
//创建树
public static Node createTree(int left,int right)
{
Node xNode = new Node();

    xNode.left  = left;
    xNode.right = right;

    if(left != right)
    {
        int mid     = (left + right) / 2;

        xNode.lNode = createTree(left,mid);         //创建左子树
        xNode.rNode = createTree(mid+1,right);      //创建右子树

    }
    return xNode;
}

//为线段树赋权值
public static void insert(Node xNode,int point, int value)
{
    xNode.sum += value;
    xNode.max = value > xNode.max ? value:xNode.max;//修改经过的节点的值   

    if(xNode.left == xNode.right)                   //找到最终节点结束
        return; 
    else
    {
        int mid  = (xNode.left + xNode.right) / 2;

        if(point <= mid)
            insert(xNode.lNode,point,value);        //向左修改
        else
            insert(xNode.rNode,point,value);        //向右修改
    }
    return;
}

//操作1:修改格子权值
public static void revise(Node xNode,int point,int value)
{
    if(xNode.left == point && xNode.right == point)
    {
        xNode.max = value;
        xNode.sum = value;
        return;
    }
    else
    {
        int mid = (xNode.left + xNode.right) / 2;

        if(point <= mid)
            revise(xNode.lNode,point,value);            //递归入,寻找节点
        else
            revise(xNode.rNode,point,value);

        xNode.sum = xNode.lNode.sum + xNode.rNode.sum;  //递归出,从下往上修改和
        xNode.max = xNode.lNode.max > xNode.rNode.max ? 
                    xNode.lNode.max : xNode.rNode.max;
    }
}
//操作2:求连续一段格子的权值和
public static int getSum(Node xNode,int left,int right)
{
    if(xNode.left == left && xNode.right == right)  //找到节点
        return xNode.sum;
    else
    {
        int mid  = (xNode.left + xNode.right) / 2;

        if(right <= mid)                            //向左子树搜索
            return getSum(xNode.lNode,left,right);
        else
            if(left > mid)                          //向右子树搜索
                return getSum(xNode.rNode,left,right);
            else                                    //左右子树分叉搜索,求和
                return getSum(xNode.lNode,left,mid) + getSum(xNode.rNode,mid+1,right);
    }
}
//操作3:求连续一段格子的最大值
public static int getMax(Node xNode,int left,int right)
{
    if(xNode.left == left && xNode.right == right)  //找到当前节点
        return xNode.max;
    else
    {
        int mid = (xNode.left + xNode.right) / 2;

        if(right <= mid)                            //搜索左子树
            return getMax(xNode.lNode,left,right);
        else
            if(left > mid)                          //搜索右子树
                return getMax(xNode.rNode,left,right);
            else                                    //左右子树分叉搜索,取最大值
                return getMax(xNode.lNode,left,mid) > getMax(xNode.rNode,mid + 1,right) ?
                       getMax(xNode.lNode,left,mid) : getMax(xNode.rNode,mid + 1,right);
    }
}
public static void main(String[] args) 
{


    int m = 0,n = 0;
    Node xNode = null;

    java.util.Scanner cin = new java.util.Scanner(System.in);

    n = cin.nextInt();
    m = cin.nextInt();

    xNode = createTree(1,n);

    for(int i = 1;i<=n;i++)
    {
        int value = cin.nextInt();
        insert(xNode,i,value);
    }

    while(m>0)
    {
        m--;
        int p,x,y;

        p = cin.nextInt();
        x = cin.nextInt();
        y = cin.nextInt();
        switch(p)
        {
        case 1 : revise(xNode,x,y); break;
        case 2 : System.out.println(getSum(xNode,x,y)); break;
        case 3 : System.out.println(getMax(xNode,x,y)); break;
        default:                                        break;
        }
    }
    cin.close();
    return;

}

}


  • 写回答

1条回答 默认 最新

  • 微wx笑 Java领域优质创作者 2015-01-21 05:04
    关注
     package main;
    import java.util.Scanner;
    public class Main {
     private Integer[] shuzu;
     public static void main(String[] args) {
      Scanner scan = new Scanner(System.in);
      String str = scan.nextLine();
      String[] str1 = str.split(" ");
      String caozuo = str1[1];
      Main main = new Main(str1[0]);
      String initNum = scan.nextLine();
      main.init(initNum);
      for (int i = 0; i < Integer.valueOf(caozuo); i++) {
       String operator = scan.nextLine();
       String[] operators = operator.split(" ");
       int num1 = Integer.valueOf(operators[1]);
       int num2 = Integer.valueOf(operators[2]);
       switch (operators[0]) {
       case "1":
        main.service1(num1,num2);
        break;
       case "2":
        main.service2(num1,num2);
        break;
       case "3":
        main.service3(num1,num2);
       }
      }
     }
     public Main(String x) {
      Integer i = Integer.valueOf(x);
      this.shuzu = new Integer[i];
     }
     public void init(String str) {
      String[] strNums = str.split(" ");
      for (int i = 0; i < strNums.length; i++) {
       this.shuzu[i] = Integer.valueOf(strNums[i]);
      }
     }
     private void service1(int x, int y) {
      this.shuzu[--x] = y;
     }
     private void service2(int x, int y) {
      int total=0;
      for(;x<=y;x++){
       total += this.shuzu[x-1];
      }
      System.out.println(total);
     }
     private void service3(int x, int y) {
      int maxNum =0;
      for(;x<=y;x++){
       if(maxNum<this.shuzu[x-1])
       {
        maxNum=this.shuzu[x-1];
       }
      }
      System.out.println(maxNum);
     }
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥15 win11家庭中文版安装docker遇到Hyper-V启用失败解决办法整理
  • ¥15 gradio的web端页面格式不对的问题
  • ¥15 求大家看看Nonce如何配置
  • ¥15 Matlab怎么求解含参的二重积分?
  • ¥15 苹果手机突然连不上wifi了?
  • ¥15 cgictest.cgi文件无法访问
  • ¥20 删除和修改功能无法调用
  • ¥15 kafka topic 所有分副本数修改
  • ¥15 小程序中fit格式等运动数据文件怎样实现可视化?(包含心率信息))
  • ¥15 如何利用mmdetection3d中的get_flops.py文件计算fcos3d方法的flops?