树的题目集

二叉树

cs 复制代码
#include <stdio.h>
#include <math.h>
#include <limits.h>

#define MAX 100005

int main(int argc, char *argv[])
{
  int n;
  scanf("%d",&n);
  int a[MAX];
  for(int i=1;i<=n;i++)
  {
    scanf("%d",&a[i]);
  }
  long long maxsum=LLONG_MIN;
  int result_depth=1;
  int depth=1;
  int start=1;
  while(start<=n)
  {
    long long sum=0;
    int end=pow(2,depth)-1;
    if(end>n) end=n;
    for(int i=start;i<=end;i++)
    {
      sum+=a[i];
    }
    if(sum>maxsum) 
    {
      maxsum=sum;
      result_depth=depth;
    }
    depth++;
    start=end+1;
  }
  printf("%d",result_depth);
  return 0;
}

线段树(高效处理区间查询和区间更新问题)

cs 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define MOD 1000000007
#define MAX 16
#define MAXSIZE (1<<MAX)
long long tree[4*MAXSIZE];

void build(int node,int l,int r,int a[])
{
  if(l==r)
  {
    tree[node]=a[l]%MOD;
    return;
  }
  int mid=(l+r)/2;
  build(node*2,l,mid,a);
  build(node*2+1,mid+1,r,a);
  tree[node]=(tree[node*2]*tree[node*2+1]%MOD);
}

void update(int node,int l,int r,int pos,int val)
{
  if(l==r)
  {
    tree[node]=val%MOD;
    return;
  }
  int mid=(l+r)/2;
  if(pos<=mid)
  {
    update(node*2,l,mid,pos,val);
  }
  else update(node*2+1,mid+1,r,pos,val);
  tree[node]=(tree[node*2]*tree[node*2+1])%MOD;
}

int main(int argc, char *argv[])
{
  int n,q;
  scanf("%d %d",&n,&q);
  int size=pow(2,n);
  int a[size+5];
  for(int i=1;i<=size;i++)
  {
    scanf("%d",&a[i]);
  }
  build(1,1,size,a);
  for(int i=0;i<q;i++)
  {
    int x,v;
    scanf("%d %d",&x,&v);
    update(1,1,size,x,v);
    printf("%lld\n",tree[1]);
  }
  return 0;
}
cs 复制代码
#include <stdio.h>

#define MAXN 100005

long long tree[4 * MAXN];
int arr[MAXN];

// 建树
void build(int node, int l, int r) {
    if (l == r) {
        tree[node] = arr[l];
        return;
    }
    int mid = (l + r) / 2;
    build(node * 2, l, mid);
    build(node * 2 + 1, mid + 1, r);
    tree[node] = tree[node * 2] + tree[node * 2 + 1];
}

// 单点更新:位置 pos 增加 val
void update(int node, int l, int r, int pos, int val) {
    if (l == r) {
        tree[node] += val;
        return;
    }
    int mid = (l + r) / 2;
    if (pos <= mid) {
        update(node * 2, l, mid, pos, val);
    } else {
        update(node * 2 + 1, mid + 1, r, pos, val);
    }
    tree[node] = tree[node * 2] + tree[node * 2 + 1];
}

// 区间查询:[ql, qr] 的和
long long query(int node, int l, int r, int ql, int qr) {
    if (ql <= l && r <= qr) {
        return tree[node];
    }
    if (r < ql || l > qr) {
        return 0;
    }
    int mid = (l + r) / 2;
    return query(node * 2, l, mid, ql, qr) +
           query(node * 2 + 1, mid + 1, r, ql, qr);
}

int main() {
    int n;
    scanf("%d", &n);
    
    for (int i = 1; i <= n; i++) {
        scanf("%d", &arr[i]);
    }
    
    build(1, 1, n);
    
    int m;
    scanf("%d", &m);
    
    for (int i = 0; i < m; i++) {
        int op, x, y;
        scanf("%d %d %d", &op, &x, &y);
        
        if (op == 1) {
            // 单点增加
            update(1, 1, n, x, y);
        } else {
            // 区间求和
            printf("%lld\n", query(1, 1, n, x, y));
        }
    }
    
    return 0;
}
cs 复制代码
#include <stdio.h>
#include <string.h>

#define MAXN 200005

int a[MAXN];
int tree[4 * MAXN];
int n, q;

// 建树:维护区间最大值
void build(int node, int l, int r) {
    if (l == r) {
        tree[node] = a[l];
        return;
    }
    int mid = (l + r) / 2;
    build(node * 2, l, mid);
    build(node * 2 + 1, mid + 1, r);
    tree[node] = tree[node * 2] > tree[node * 2 + 1] ? 
                 tree[node * 2] : tree[node * 2 + 1];
}

// 查询区间 [ql, qr] 的最大值
int query(int node, int l, int r, int ql, int qr) {
    if (ql <= l && r <= qr) {
        return tree[node];
    }
    if (r < ql || l > qr) {
        return -1;
    }
    int mid = (l + r) / 2;
    int left_max = query(node * 2, l, mid, ql, qr);
    int right_max = query(node * 2 + 1, mid + 1, r, ql, qr);
    return left_max > right_max ? left_max : right_max;
}

int main() {
    scanf("%d %d", &n, &q);
    
    for (int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
    }
    
    build(1, 1, n);
    
    for (int i = 0; i < q; i++) {
        int l, r;
        scanf("%d %d", &l, &r);
        
        if (r - l <= 1) {
            // 区间长度 ≤ 2,没有中间元素
            printf("NO\n");
            continue;
        }
        
        int max_val = a[l] > a[r] ? a[l] : a[r];
        int max_mid = query(1, 1, n, l + 1, r - 1);
        
        printf("%s\n", max_mid > max_val ? "YES" : "NO");
    }
    
    return 0;
}
相关推荐
To_OC17 小时前
LC 207 课程表:刚学图论那会儿,我连这是拓扑排序都没看出来
javascript·算法·leetcode
To_OC17 小时前
LC 208 实现 Trie 前缀树:曾被名字劝退,写完发现是送分题
javascript·算法·leetcode
BadBadBad__AK19 小时前
线段树维护区间 k 次方和
c++·数学·算法·stl
_清歌1 天前
DSpark 深度解读:DeepSeek-V4 如何用「半自回归」把推理速度提升 85%
算法
统计实现局1 天前
SVD 的三步走:双对角化、Givens 收敛、排序
算法
躬行见万象1 天前
《VLA 系列》UniLab 强化训练 | G1 机器人 |复现
算法
统计实现局1 天前
对称不定分解(Bunch-Kaufman):为什么 Cholesky 不够用
算法
统计实现局1 天前
dqrsl 拆解:拿着 QR 结果能算出哪 5 种东西
算法
统计实现局1 天前
为什么 Cholesky 求逆比 Gauss-Jordan 快一倍——行列式溢出防护详
算法