hihocoder 1078 线段树的区间修改 java实现

package tree;


import java.util.Scanner;


/*

 * 10

4733 6570 8363 7391 4511 1433 2281 187 5166 378

 */

public class Week20 {


private static int dataIndex = 0;

private static int sum = 0;

public static void main(String[] args) {

Scanner scanner = new Scanner(System.in);

int datanum = Integer.parseInt(scanner.nextLine());

String data = scanner.nextLine();

node20 root =creSegTree(1, datanum, data);

int querynum = Integer.parseInt(scanner.nextLine());

for(int i=0; i<querynum; i++){

String querydata = scanner.nextLine();

int querytype = Integer.parseInt(querydata.split(" ")[0]);

if(querytype == 1){

int leftBound = Integer.parseInt(querydata.split(" ")[1]);

int rightBound = Integer.parseInt(querydata.split(" ")[2]);

int newValue = Integer.parseInt(querydata.split(" ")[3]);

update(root, leftBound, rightBound, newValue);

}

if(querytype == 0){

int leftBound = Integer.parseInt(querydata.split(" ")[1]);

int rightBound = Integer.parseInt(querydata.split(" ")[2]);

query(root, leftBound, rightBound);

System.out.println(sum);

sum = 0;

}

}

}

public static node20 creSegTree(int leftBound, int rightBound, String data){

node20 node = new node20(leftBound, rightBound);

if(leftBound != rightBound){

node20 leftchild = creSegTree(leftBound, (leftBound + rightBound) / 2, data);

node20 rightchild = creSegTree((leftBound + rightBound) / 2 + 1, rightBound, data);

node.leftChild = leftchild;

node.rightChild = rightchild;

node.sumValue = leftchild.sumValue + rightchild.sumValue;

return node;

}

else{

node.sumValue = Integer.parseInt(data.split(" ")[dataIndex++]);

return node;

}

}

public static void update(node20 root, int leftBound, int rightBound, int newValue){

if(leftBound == root.leftBound && rightBound == root.rightBound){ 

root.sumValue = (root.rightBound - root.leftBound + 1) * newValue;

root.lazyTag = newValue;

}

else{

if(root.lazyTag != 0){

root.leftChild.lazyTag = root.lazyTag;

root.leftChild.sumValue = (root.leftChild.rightBound - root.leftChild.leftBound + 1) * root.lazyTag;

root.rightChild.lazyTag = root.lazyTag;

root.rightChild.sumValue = (root.rightChild.rightBound - root.rightChild.leftBound + 1) * root.lazyTag;

root.lazyTag = 0;

}

if(rightBound < (root.leftBound + root.rightBound) / 2 + 1){ 

update(root.leftChild, leftBound, rightBound, newValue);

root.sumValue = root.leftChild.sumValue + root.rightChild.sumValue;

}

else if(leftBound > (root.leftBound + root.rightBound) / 2){ 

update(root.rightChild, leftBound, rightBound, newValue);

root.sumValue = root.leftChild.sumValue + root.rightChild.sumValue;

}

else{

update(root.leftChild, leftBound, (root.leftBound + root.rightBound) / 2, newValue);

update(root.rightChild, (root.leftBound + root.rightBound) / 2 + 1, rightBound, newValue);

root.sumValue = root.leftChild.sumValue + root.rightChild.sumValue;

}

}

}

public static void query(node20 root, int leftBound, int rightBound){

if(root.leftBound == leftBound && root.rightBound == rightBound) sum += root.sumValue;

else{

if(root.lazyTag != 0){

root.leftChild.lazyTag = root.lazyTag;

root.leftChild.sumValue = (root.leftChild.rightBound - root.leftChild.leftBound + 1) * root.lazyTag;

root.rightChild.lazyTag = root.lazyTag;

root.rightChild.sumValue = (root.rightChild.rightBound - root.rightChild.leftBound + 1) * root.lazyTag;

root.lazyTag = 0;

}

if(rightBound < (root.leftBound + root.rightBound) / 2 + 1){ 

query(root.leftChild, leftBound, rightBound);

}

else if(leftBound > (root.leftBound + root.rightBound) / 2){ 

query(root.rightChild, leftBound, rightBound);

}

else{

query(root.leftChild, leftBound, (root.leftBound + root.rightBound) / 2);

query(root.rightChild, (root.leftBound + root.rightBound) / 2 + 1, rightBound);

}

}

}

}


class node20{

int leftBound;

int rightBound;

int sumValue;

node20 leftChild;

node20 rightChild;

int lazyTag;

public node20(int leftBound, int rightBound){

this.leftBound = leftBound;

this.rightBound = rightBound;

}


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值