hdu 1823 Luck and Love 和 poj 1195 Mobile phones

题目:
hdu
poj

题意:
二维线段树的查找与添加

注意:

  1. 二维线段树的更新方式要全更新:
(更新范围)
.....
.....
.....
.....

有一种错误的更新方式:

(更新范围)
	.
	.
	.
.....

错误的代码

void addx(int x, int y, int v, int l, int r, int pos){
	if (l == r){
    	addy(pos, y, v, 1, Size, 1);
        return;
	} 
    int mid = (l + r) >> 1;
    if (mid >= x)
		addx(x, y, v, lson);
    else
        addx(x, y, v, rson);
    updatax(y, pos); 
}

正确的代码

void addx(int x, int v, int l, int r, int pos){
    addy(pos, b, v, 1, Size, 1);
	if (l == r)
        return;
    int mid = (l + r) >> 1;
    if (mid >= x)
		addx(x, v, lson);
    else
        addx(x, v, rson);
}

poj 1195代码

#include <iostream>
#include <algorithm>
#define lson l, mid, pos << 1
#define rson mid + 1, r, pos << 1 | 1
using namespace std;
const int MAXN = 1030;
int tree[MAXN<<2][MAXN<<2];
int Size, a, b, c, d;
void updatay(int x, int p){
	tree[x][p] = tree[x][p<<1] + tree[x][p<<1|1];
}
void addy(int x, int y, int v, int l, int r, int pos){
    if (l == r){
        tree[x][pos] += v;
        return;
    }
    int mid = (l + r) >> 1;
    if (mid >= y)
		addy(x, y, v, lson);
    else
        addy(x, y, v, rson);
    updatay(x, pos);
}
void addx(int x, int v, int l, int r, int pos){
    addy(pos, b, v, 1, Size, 1);
	if (l == r)
        return;
    int mid = (l + r) >> 1;
    if (mid >= x)
		addx(x, v, lson);
    else
        addx(x, v, rson);
}
int findy(int x, int L, int R, int l, int r, int pos){
	if (l >= L && r <= R)
		return tree[x][pos];
	int mid = (l + r) >> 1;
	int ans = 0;
	if (mid >= L)
		ans += findy(x, L, R, lson);
	if (mid < R)
		ans += findy(x, L, R, rson);
	return ans;
}
int findx(int xl, int xr, int l, int r, int pos){
	if (l >= xl && r <= xr)
		return findy(pos, b, d, 1, Size, 1);
	int mid = (l + r) >> 1;
	int ans = 0;
	if (mid >= xl)
		ans += findx(xl, xr, lson);
	if (mid < xr)
		ans += findx(xl, xr, rson);
	return ans;
}
int main(){
	int n, ans;
    while (~scanf("%d", &n) && n != 3){
    	if (n == 0)
    		scanf("%d", &Size);
    	else if (n == 1){
    		scanf("%d%d%d", &a, &b, &c);
    		b++;
    		addx(a+1, c, 1, Size, 1);
		}
		else if (n == 2){
			scanf("%d%d%d%d", &a, &b, &c, &d);
			b++;
			d++;
			ans = findx(a+1, c+1, 1, Size, 1);
			printf("%d\n", ans);
		}
    }
    return 0;
}

hdu 1823代码解法1

#include <iostream>
#include <algorithm>
#include <cstring>
#define lson l, mid, pos << 1
#define rson mid + 1, r, pos << 1 | 1
using namespace std;
const int MAXH = 110; 
const int MAXN = 1010;
int tree[MAXH<<2][MAXN<<2];
int maxh = 101, maxn = 1001;  //maxn是1001而不是1000, 因为有0.0这个元素, maxh同理 
int a, aa;
double b, c;
void updatay(int x, int p){
	tree[x][p] = max(tree[x][p<<1], tree[x][p<<1|1]);
}
void addy(int x, int y, int v, int l, int r, int pos){
    if (l == r){
        tree[x][pos] = max(tree[x][pos], v);  //可能叠加,取最大
        return;
    }
    int mid = (l + r) >> 1;
    if (mid >= y)
		addy(x, y, v, lson);
    else
        addy(x, y, v, rson);
    updatay(x, pos);
}
void addx(int x, int v, int l, int r, int pos){
    addy(pos, (int)b, v, 1, maxn, 1);
	if (l == r)
        return;
    int mid = (l + r) >> 1;
    if (mid >= x)
		addx(x, v, lson);
    else
        addx(x, v, rson);
}
int findy(int x, int L, int R, int l, int r, int pos){
	if (l >= L && r <= R)
		return tree[x][pos];
	int mid = (l + r) >> 1;
	int ans = 0;
	if (mid >= L)
		ans = findy(x, L, R, lson);
	if (mid < R)
		ans = max(ans, findy(x, L, R, rson));
	return ans;
}
int findx(int xl, int xr, int l, int r, int pos){
	if (l >= xl && r <= xr)
		return findy(pos, (int)b, (int)c, 1, maxn, 1);
	int mid = (l + r) >> 1;
	int ans = 0;
	if (mid >= xl)
		ans = findx(xl, xr, lson);
	if (mid < xr)
		ans = max(ans, findx(xl, xr, rson));
	return ans;
}
int main(){
	int m;
	double ans;
	char op;
    while (~scanf("%d", &m) && m != 0){
    	memset(tree, 0, sizeof(tree));
    	while (m--){
    		scanf(" %c", &op);
    		if (op == 'I'){
    			scanf("%d%lf%lf", &a, &b, &c);
    			a = a - 99;
				b = b * 10 + 1;
    			c = c * 10 + 1;  //缘分值向右偏移 1 ,为什么?因为线段树初始化为0,缘分值也有0,会冲突,既无法判断范围内有没有mm
    			addx(a, (int)c, 1, maxh, 1);
			}
			else{
				scanf("%d%d%lf%lf", &a, &aa, &b, &c);
				a = a - 99;
				aa = aa - 99;
				b = b * 10 + 1;
    			c = c * 10 + 1;
    			if (a > aa)
    				swap(a, aa);  //这是个坑
    			if (b > c)
    				swap(b, c);  //这是个坑
    			ans = (findx(a, aa, 1, maxh, 1) - 1) * 1.0 / 10;
    			if (ans < 0) // ans == -0.1
    				printf("-1\n");
    			else
					printf("%.1lf\n", ans);
			}
		}
    }
    return 0;
}

hdu 1823代码解法2

#include <iostream>
#include <algorithm>
#include <cstring>
#define lson l, mid, pos << 1
#define rson mid + 1, r, pos << 1 | 1
using namespace std;
const int MAXH = 110; 
const int MAXN = 1010;
int tree[MAXH<<2][MAXN<<2];
int maxh = 101, maxn = 1001;  //maxn是1001而不是1000, 因为有0.0这个元素, maxh同理 
int a, aa;
double b, c;
void updatay(int x, int p){
	tree[x][p] = max(tree[x][p<<1], tree[x][p<<1|1]);
}
void addy(int x, int y, int v, int l, int r, int pos){
    if (l == r){
        tree[x][pos] = max(tree[x][pos], v);  //可能叠加 
        return;
    }
    int mid = (l + r) >> 1;
    if (mid >= y)
		addy(x, y, v, lson);
    else
        addy(x, y, v, rson);
    updatay(x, pos);
}
void addx(int x, int v, int l, int r, int pos){
    addy(pos, (int)b, v, 1, maxn, 1);
	if (l == r)
        return;
    int mid = (l + r) >> 1;
    if (mid >= x)
		addx(x, v, lson);
    else
        addx(x, v, rson);
}
int findy(int x, int L, int R, int l, int r, int pos){
	if (l >= L && r <= R)
		return tree[x][pos];
	int mid = (l + r) >> 1;
	int ans = -1;
	if (mid >= L)
		ans = findy(x, L, R, lson);
	if (mid < R)
		ans = max(ans, findy(x, L, R, rson));
	return ans;
}
int findx(int xl, int xr, int l, int r, int pos){
	if (l >= xl && r <= xr)
		return findy(pos, (int)b, (int)c, 1, maxn, 1);
	int mid = (l + r) >> 1;
	int ans = -1;
	if (mid >= xl)
		ans = findx(xl, xr, lson);
	if (mid < xr)
		ans = max(ans, findx(xl, xr, rson));
	return ans;
}
int main(){
	int m;
	double ans;
	char op;
    while (~scanf("%d", &m) && m != 0){
    	memset(tree, -1, sizeof(tree));
    	while (m--){
    		scanf(" %c", &op);
    		if (op == 'I'){
    			scanf("%d%lf%lf", &a, &b, &c);
    			a = a - 99;
				b = b * 10 + 1;
    			c = c * 10;   //不用偏移,因为线段树初始化为-1,不与0.0冲突
    			addx(a, (int)c, 1, maxh, 1);
			}
			else{
				scanf("%d%d%lf%lf", &a, &aa, &b, &c);
				a = a - 99;
				aa = aa - 99;
				b = b * 10 + 1;
    			c = c * 10 + 1;
    			if (a > aa)
    				swap(a, aa);  //...
    			if (b > c)
    				swap(b, c);  //...
    			ans = findx(a, aa, 1, maxh, 1) * 1.0 / 10;
    			if (ans == -1)
    				printf("-1\n");
    			else
					printf("%.1lf\n", ans);
			}
		}
    }
    return 0;
}
上一篇:N-gram理解


下一篇:后妈茶话会_歌词(Tough Love)