线段树的存储结构:
线段树的实现:
typedef struct node
{
int ld,rd;
struct node *lc, *rc;
keytype key;
} node;
建空树:
node* buildtree( int a, int b )
{
node* p = { 给p申请一块内存}
p -> ld = a; p -> rd = b;
{初始化p->key}
if ( a == b ) return p;
p -> lc = buildtree( a, ( a + b ) / 2 );
p -> rc = buildtree( ( a + b ) / 2 + 1, b );
return p;
}
插入线段:
void insert( node *T, int a, int b, keytype key )
{
if ( a <= T -> ld && T -> rd <= b )
{根据key处理T->key; return; }
if ( a <= ( T -> ld + T -> rd ) / 2 )
insert( T -> lc, a, b, key );
if ( b > ( T -> ld + T -> rd ) / 2 )
insert( T -> rc, a, b, key );
{根据T->lc和T->rc的信息处理T->key}
}
查找线段[a,b]的key值:
keytype search( node *T, int a, int b )
{
keytype res;
if ( a <= T -> ld && T -> rd <= b )
{根据T -> key处理res; return res; }
if ( a <= ( T -> ld + T -> rd ) / 2 )
{根据search( T -> lc, a, b )处理res}
if ( b > ( T -> ld + T -> rd ) / 2 )
{根据search( T -> rc, a, b )处理res}
return res;
}
对于线段树,用数组来模拟指针对于计算机实现比较快,可能与cache预测相关。
jobdu1496:
#include <stdio.h>
#include <string.h>
#define INVALID -1
typedef struct _node
{
int lb;
int rb;
int key;
} Node;
typedef struct _sq
{
int left;
int right;
int key;
} Sq;
Sq sq[100006];
Node node[3000006];
int node_ind;
int sq_ind;
int n, m;
void buildtree(int l, int r, int index)
{
node[index].lb = l;
node[index].rb = r;
node[index].key = 0;
if (l != r)
{
buildtree(l, (l+r)>>1, index<<1);
buildtree(1+((l+r)>>1), r, 1+(index<<1));
}
}
void insert(int index, int l, int r, int key)
{
int mid;
if (l<=node[index].lb && r>=node[index].rb) /* 插入的范围覆盖整个区间 */
{ node[index].key = key; }
else { /* 不覆盖整个区间 */
if (node[index].key > 0)
{
node[index<<1].key = node[index].key;
node[1+(index<<1)].key = node[index].key;
}
node[index].key = INVALID; /* 当前这段的key值 无效*/
mid = (node[index].lb+node[index].rb)>>1;
if (l <= mid)
{ insert(index<<1, l, r, key); } /* 和左区间重叠 */
if (r > mid) /* 和右区间重叠 */
{ insert(1+(index<<1), l, r, key); }
}
}
void search(int index)
{
if (node[index].key == INVALID)
{
search(index<<1);
search(1+(index<<1));
} else if (node[index].key != 0) {
sq[sq_ind].left = node[index].lb;
sq[sq_ind].right = node[index].rb;
sq[sq_ind++].key = node[index].key;
}
}
int main(void)
{
int i;
int left, right;
int maxcnt, count;
while(scanf("%d%d", &n, &m) !=EOF)
{
node_ind = 0;
buildtree(1, n, 1);
for (i=1; i<=m; i++)
{
scanf("%d%d", &left, &right);
insert(1, left, right, i);
}
sq[0].right = sq[0].right = sq_ind = 0;
search(1);
count = maxcnt = sq[0].right - sq[0].left + 1;
for (i=1; i<sq_ind; i++)
{
count = count * (sq[i].key == sq[i-1].key) + sq[i].right - sq[i].left + 1;
maxcnt = count > maxcnt ? count : maxcnt;
}
printf("%d\n", maxcnt);
}
return 0;
}
答案没用用线段树写得非常好!!!
#include <stdio.h>
int next[1000010];
int a[1000010];
struct E {
int l;
int r;
}list[100010];
int main () {
int n ,m;
while (scanf ("%d%d",&n,&m) == 2) {
for (int i = 1;i <= n;i ++) {
a[i] = 0;
next[i] = i + 1;
}
for (int i = 1;i <= m;i ++) {
scanf ("%d%d",&list[i].l,&list[i].r);
}
for (int j = m;j >= 1;j --) {
int l = list[j].l, r = list[j].r;
for (int i = l;i <= r;) {
if (a[i] == 0) {
a[i] = j;
}
int tmp = next[i];
next[i] = next[r]>tmp ? next[r]:tmp;
i = tmp;
}
}
int ans = 0;
int cnt = 0;
for (int i = 1;i <= n;i ++) {
if (a[i] == 0 || i != 1 && a[i] != a[i - 1]) {
if (cnt > ans) {
ans = cnt;
}
if (a[i] != 0)
cnt = 1;
else
cnt = 0;
}
else cnt ++;
}
if (cnt > ans)
ans = cnt;
printf("%d\n",ans);
}
return 0;
}