c语言蓝桥杯的操作格子我用了提示的线段树求解但是为什么运行还是超时呢?请大家帮帮忙!谢谢!

c语言爱好者嘻嘻 2014-02-04 08:00:23
问题描述
有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。
#include<stdio.h>
#include<stdlib.h>
typedef struct caozuo
{
int p;
int x;
int y;
}cao_zuo;
typedef struct shu
{
int zuo;
int you;
int max;
int sum;
struct shu *_zuo,*_you;
}_shu;
void chuangjian(_shu **geng,int *x,int zuo1,int you1)
{
*geng=(_shu*)malloc(sizeof(_shu));
(*geng)->zuo=zuo1;
(*geng)->you=you1;
if(zuo1==you1)
{
(*geng)->max=x[zuo1-1];
(*geng)->sum=x[zuo1-1];
(*geng)->_zuo=NULL;
(*geng)->_you=NULL;
}
else if(zuo1<=you1)
{
chuangjian(&((*geng)->_zuo),x,zuo1,(zuo1+you1)/2);
chuangjian(&((*geng)->_you),x,(zuo1+you1)/2+1,you1);
(*geng)->max=(*geng)->_zuo->max>(*geng)->_you->max?(*geng)->_zuo->max:(*geng)->_you->max;
(*geng)->sum=(*geng)->_zuo->sum+(*geng)->_you->sum;
}
}
int fda(_shu **geng,int zuo1,int you1)
{
int da;
if(zuo1<=(*geng)->zuo&&(*geng)->you<=you1)
{
da=(*geng)->max;
}
else
{
if(zuo1<=((*geng)->zuo+(*geng)->you)/2)
{
da=fda(&((*geng)->_zuo),zuo1,you1);
}
if(((*geng)->zuo+(*geng)->you)/2+1<=you1)
{
da=fda(&((*geng)->_you),zuo1,you1);
}
if(zuo1<=((*geng)->zuo+(*geng)->you)/2&&((*geng)->zuo+(*geng)->you)/2+1<=you1)
{
da=fda(&((*geng)->_zuo),zuo1,you1)>fda(&((*geng)->_you),zuo1,you1)?fda(&((*geng)->_zuo),zuo1,you1):fda(&((*geng)->_you),zuo1,you1);
}
}
return da;
}
int fsum(_shu **geng,int zuo1,int you1)
{
int s=0;
if(zuo1<=(*geng)->zuo&&(*geng)->you<=you1)
{
s+=(*geng)->sum;
}
else
{
if(zuo1<=((*geng)->zuo+(*geng)->you)/2)
s+=fsum(&((*geng)->_zuo),zuo1,you1);
if(((*geng)->zuo+(*geng)->you)/2+1<=you1)
s+=fsum(&((*geng)->_you),zuo1,you1);
}
return s;
}
void fxiu(_shu **geng,int x1,int y1)
{
if((*geng)->zuo==(*geng)->you)
{
(*geng)->sum=y1;
(*geng)->max=y1;
}
else
{
if(x1<=((*geng)->zuo+(*geng)->you)/2)
fxiu(&((*geng)->_zuo),x1,y1);
if(x1>=((*geng)->you+(*geng)->zuo)/2+1)
fxiu(&((*geng)->_you),x1,y1);
(*geng)->sum=(*geng)->_zuo->sum+(*geng)->_you->sum;
(*geng)->max=(*geng)->_zuo->max>(*geng)->_you->max?(*geng)->_zuo->max:(*geng)->_you->max;
}
}
int main()
{
int n,m,*yuanshu,i;
cao_zuo *cao;
_shu *xianduanshu;
scanf("%d%d",&n,&m);
yuanshu=(int*)malloc(n*sizeof(int));
cao=(cao_zuo*)malloc(m*sizeof(cao_zuo));
for(i=0;i<n;i++)
scanf("%d",&yuanshu[i]);
for(i=0;i<m;i++)
scanf("%d%d%d",&cao[i].p,&cao[i].x,&cao[i].y);
chuangjian(&xianduanshu,yuanshu,1,n);
for(i=0;i<m;i++)
{
switch(cao[i].p)
{
case 1:fxiu(&xianduanshu,cao[i].x,cao[i].y);break;
case 2:printf("%d\n",fsum(&xianduanshu,cao[i].x,cao[i].y));break;
case 3:printf("%d\n",fda(&xianduanshu,cao[i].x,cao[i].y));break;
}
}
return 0;
}
...全文
490 点赞 收藏 7
写回复
7 条回复
空瑾瑜 2015年03月05日
我用JAVA改写也是超时,求解!
回复 点赞
学海乌鸦 2014年12月17日
我用java写的,算法思路几乎完全参考了楼上的楼上的博客 但还是超时了,求解啊
import java.util.Scanner;


public class Main {

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int n = scanner.nextInt();
		int m = scanner.nextInt();
		Tree tree = createTree(1, n);
		for (int i = 1; i <= n; i++) {
			insert(tree, scanner.nextInt(), i);
		}
		int order[][] = new int[m][3];
		for (int i = 0; i < order.length; i++) {
			for (int j = 0; j < order[0].length; j++) {
				order[i][j] = scanner.nextInt();
			}
		}
		for (int i = 0; i < order.length; i++) {
			switch (order[i][0]) {
			case 1:
				change(tree,order[i][1],order[i][2]);
				break;
			case 2:
				System.out.println(getsum(tree,order[i][1],order[i][2]));
				break;
			case 3:
				System.out.println(getmax(tree,order[i][1],order[i][2]));
				break;

			default:
				break;
			}
		}

	}


	private static int getsum(Tree tree, int i, int j) {
		if (tree.left==i&&tree.right==j) {
			return tree.sum;
		}
		int mid = (tree.left + tree.right) / 2;
		if (j<=mid) {
			return getsum(tree.lchild, i, j);
			
		}
		else if (i>mid) {
			return getsum(tree.rchild, i, j);
		}
		else {
			return getsum(tree.lchild, i, mid)+getsum(tree.rchild, mid+1, j);
		}
	}

	private static int getmax(Tree tree, int i, int j) {
		// TODO Auto-generated method stub
		if (tree.left==i&&tree.right==j) {
			return tree.max;
		}
		int mid = (tree.left + tree.right) / 2;
		if (j<=mid) {
			return getmax(tree.lchild, i, j);
			
		}else if (i>mid) {
			return getmax(tree.rchild, i, j);
		}
		else {
			return max(getmax(tree.lchild, i, mid),getmax(tree.rchild, mid+1, j));
		}
	}

	private static void change(Tree tree, int i, int j) {
		// TODO Auto-generated method stub
		if (tree.left == tree.right ) {
			tree.max = j;
			tree.sum = j;
			return;
		}
		int mid = (tree.left + tree.right) / 2;
		if (i <= mid) {
			change(tree.lchild, i, j);
			
		} else {
			change(tree.rchild, i, j);
		}
		tree.max=max(tree.lchild.max,tree.rchild.max);
		tree.sum=tree.lchild.sum+tree.rchild.sum;
	}

	private static int max(int max, int max2) {
		// TODO Auto-generated method stub
		return max>max2?max:max2;
	}

	private static void insert(Tree tree, int a, int index) {
		tree.max = max(tree.max, a);
		tree.sum +=a;
		if (tree.left == tree.right) {
			
			return;
		}
		if (index <= ((tree.left + tree.right) / 2)) {
			insert(tree.lchild, a, index);
		} else {
			insert(tree.rchild, a, index);
		}
	}

	static Tree createTree(int min, int max) {
		Tree tree = new Tree();
		tree.left = min;
		tree.right = max;
		tree.max = 0;
		tree.sum = 0;
		if (min == max) {
			return tree;
		}
		int mid = (min + max) / 2;

		tree.lchild = createTree(min, mid);
		tree.rchild = createTree(mid + 1, max);
		return tree;
	}

}

class Tree {
	int max, sum;
	int left, right;
	Tree lchild, rchild;
}
回复 点赞
c语言爱好者嘻嘻 2014年02月11日
太感谢了,我对比了一下和我的有些不同,主要是创建时我就一边赋值了,还有就是求最大指时与你的有点不同,其他的基本类似,我想问一下我的程序超时在哪里?可以帮看看吗?
回复 点赞
云笔记 2014年02月07日
这是我写的。 蓝桥杯:操作格子(线段树)http://blog.csdn.net/u013055228/article/details/18965325
回复 点赞
sandikast 2014年02月05日
http://blog.sbw.so/Article/index/title/蓝桥杯%20算法训练%20操作格子%20使用线段树解法.html
回复 点赞
c语言爱好者嘻嘻 2014年02月05日
连接打不开,你说的什么呢
回复 点赞
发动态
发帖子
C语言
创建于2007-09-28

3.2w+

社区成员

24.0w+

社区内容

C语言相关问题讨论
社区公告
暂无公告