您的位置:首页 > 其它

POJ 2528 Mayor's posters (线段树+离散化)

2012-04-09 19:26 495 查看
题目链接:ヽ(ˋ▽ˊ)ノ 哎~网上看了老久,才知道怎么离散化,郁闷,建树前需要离散化点, 用p[i][2]来存储每个点离散化前的信息, 用结构体num来存储每个点的具体信息code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
int num, id , left;//该点的数值, 为哪条线段的, 左端点还是右端点
}node;
node num[2*20005];
struct Tnode
{
int left, right, color;
}tree[4*20005];
int p[10005][2], sum = 0, flag[20005];

int cmp( const void *a ,const void *b)
{
return (*(node *)a).num>(*(node *)b).num?1:-1;
}
void build(int root, int left, int right)
{
int mid = (left+right)/2;
if(left == right)
{
tree[root].left = tree[root].right = left;
tree[root].color = 0;
return ;
}
tree[root].left = left; tree[root].right = right; tree[root].color = 0;
build(2*root, left, mid);
build(2*root+1, mid+1, right);
}

void insert(int root, int left, int right, int color)
{
int mid = (tree[root].left+tree[root].right)/2;
if(tree[root].left == left && tree[root].right == right)
{
tree[root].color = color;
return ;
}
if(tree[root].color)
{
tree[2*root].color = tree[root].color;
tree[2*root+1].color = tree[root].color;
tree[root].color = 0;
}
if(right<=mid)
insert(2*root, left, right, color);
else if(left>mid)
insert(2*root+1, left, right, color);
else
{
insert(2*root, left, mid, color);
insert(2*root+1, mid+1, right, color);
}
}
void query(int root)
{
if(tree[root].color)
{
if(!flag[tree[root].color])
{
flag[tree[root].color] = 1;
sum++;
}
return ;
}
query(2*root);
query(2*root+1);
}
int main()
{
int i = 0, n = 0, t = 0, k = 0, pre = 0, index = 0;
scanf("%d",&t);
while(t--)
{
k = 0;
scanf("%d",&n);
for(i = 0; i<n; i++)
{
scanf("%d %d",&p[i][0], &p[i][1]);
num[k].num = p[i][0];//用num来存储该点的信息有为第几段, 端点位, 数值
num[k].id = i;
num[k++].left = 1;
num[k].num = p[i][1];
num[k].id = i;
num[k++].left = 0;
}
qsort(num, k, sizeof(num[0]), cmp);//对结构体中的数值排序
pre = -1; index = 0;//用index来确定离散化后的范围
for(i = 0; i<2*n; i++)
{
if(num[i].num != pre)//不是重复的点范围加一
{
index++;
pre = num[i].num;
}
if(num[i].left)
p[num[i].id][0] = index;
else
p[num[i].id][1] = index;
}//离散化完毕
build(1, 1, index);
for(i = 0; i<n; i++)
insert(1, p[i][0], p[i][1], i+1);//对线段进行上色
sum = 0;
memset(flag, 0, sizeof(flag));//判重
query(1);
printf("%d\n",sum);
}
return 0;
}
code:简单点的离散化离散化时注意相邻两点的离散化数据1 101 36 10不能离散化成4个点, 要离散化为5个点, 应为3与6在没离散化前是图了色的, 离散化完后不能忽略了这个区间
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int sum = 0, p[10005][2],  num[20005], num1[100005], tree[50005*6], used[100005];
int cmp(const void *a, const void *b)
{
return *(int *)a-*(int *)b;
}
void build(int root, int left, int right)
{
int mid = (left+right)/2;
if(left == right)
{
tree[root] = 0;
return;
}
tree[root] = 0;
build(2*root, left, mid);
build(2*root+1, mid+1, right);
}
void insert(int root, int left, int right, int start, int end, int col)
{
int mid = (left+right)/2;
if(num1[left] >= start && num1[right] <= end)
{
tree[root] = col;
return ;
}
if(tree[root] != 0)
{
tree[2*root] = tree[2*root+1] = tree[root];
tree[root] = 0;
}
if(num1[mid]>=start)
insert(2*root, left, mid, start, end, col);
if(num1[mid]<end)
insert(2*root+1, mid+1, right, start, end, col);
}
void query(int root, int left, int right)
{
int col = tree[root], mid = (left+right)/2;
if(col != 0)
{
if(!used[col])
{
used[col] = 1;
sum++;
}
return ;
}
if(left == right)
return;
query(2*root, left, mid);
query(2*root+1, mid+1, right);
}
int main()
{
int t = 0, i = 0, n = 0, k = 0, index = 0, pre = -1;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
k = 1;
for(i = 0; i<n; i++)
{
scanf("%d %d",&p[i][0], &p[i][1]);
num[k++] = p[i][0];
num[k++] = p[i][1];
}
num[0] = 0;
qsort(num, k, sizeof(num[0]), cmp);
pre = -1; index = 1;
num[0] = num[1];
for(i = 1; i<k; i++)
{
if(num[i]-num[i-1]>1)
num1[index++] = num[i]-1;
if(num[i] != pre)
{
num1[index++] = num[i];
pre = num[i];
}
}
build(1, 1, index-1);
//memset(tree, 0, 6*index*sizeof(tree[0]));
memset(used,0,sizeof(used));
for(i = 0; i<n; i++)
insert(1, 1, index-1, p[i][0], p[i][1], i+1);
sum = 0;
query(1, 1, index-1);
printf("%d\n",sum);
}
return 0;
}
这代码错的也能过...........
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define N 20002
using namespace std;
struct node
{
int x, y;
}p
;
int cnt = 0, ans = 0, id = 0, X[2*N], t[3*N], used
;

void update(int c, int l, int r, int lf, int rt, int col)
{
int m = l+(r-l)/2;
if(lf<=X[l] && rt>=X[r])
{
t[c] = col;
return ;
}
if(t[c])
{
t[2*c] = t[2*c+1] = t[c];
t[c] = 0;
}
if(lf<=X[m]) update(2*c, l, m, lf, rt, col);
if(rt>X[m]) update(2*c+1, m+1, r, lf, rt, col);
}

void query(int c, int l, int r)
{
int m = l+(r-l)/2;
if(t[c] && !used[t[c]])
{
ans++;
used[t[c]] = 1;
}
if(t[c]) return ;
if(l == r)
return ;
query(2*c, l, m);
query(2*c+1, m+1, r);
}

int main()
{
//freopen("input.txt", "r", stdin);
int i = 0, c = 0, n = 0;
scanf("%d", &c);
while(c--)
{
memset(used, 0, sizeof(used));
memset(t, 0, sizeof(t));
cnt = ans = 0;
scanf("%d", &n);
for(i = 0; i<n; i++)
{
scanf("%d %d", &p[i].x, &p[i].y);
X[cnt++] = p[i].x;
X[cnt++] = p[i].y;
}
sort(X, X+cnt);
cnt = unique(X, X+cnt)-X;
for(i = 0; i<n; i++)
update(1, 0, cnt-1, p[i].x, p[i].y, i+1);
query(1, 0, cnt-1);
printf("%d\n", ans);
}
return 0;
}

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: