树的题目集

二叉树

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;
}
相关推荐
仟濹2 小时前
【算法打卡day30(2026-03-23 周一)】BFSDFS孤岛题型-复习 & 第15届蓝桥杯省赛B组C++
c++·算法·蓝桥杯
不染尘.2 小时前
拓扑排序算法
开发语言·数据结构·c++·算法·排序算法·广度优先·深度优先遍历
m0_518019482 小时前
高性能日志库C++实现
开发语言·c++·算法
UnicornDev2 小时前
从零开始的C++编程之旅——第六篇:数组与字符串——批量数据的存储与处理
java·开发语言·算法
阿里嘎多哈基米2 小时前
速通Hot100-Day10——二叉树
算法·leetcode·二叉树·递归·平衡二叉树
chushiyunen2 小时前
BM25稀疏检索算法笔记
笔记·算法·c#
芸忻2 小时前
day 23 第七章 回溯算法part02代码随想录算法训练营71期
算法
qq_334903152 小时前
C++中的装饰器模式高级应用
开发语言·c++·算法
jyyyx的算法博客2 小时前
LC406. 基于身高重建队列【贪心】
算法