树、堆的题目集

星际编码大战

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

#define MAX 128

typedef long long ll;

typedef struct MinHeap
{
  ll* data;
  int size;
  int capacity;
}MinHeap;

MinHeap* createHeap(int cap)
{
  MinHeap* heap=(MinHeap*)malloc(sizeof(MinHeap));
  heap->data=(ll*)malloc(sizeof(ll)*(cap+1));
  heap->size=0;
  heap->capacity=cap;
  return heap;
}

void swap(ll* a,ll* b)
{
  ll t=*a;
  *a=*b;
  *b=t;
}

void heapifyup(MinHeap* heap,int idx)
{
  while(idx>1&&heap->data[idx]<heap->data[idx/2])
  {
    swap(&heap->data[idx],&heap->data[idx/2]);
    idx=idx/2;
  }
}

void heapifydown(MinHeap* heap,int idx)
{
  while(idx*2<=heap->size)
  {
    int left=idx*2;
    int right=left+1;
    int smallest=idx;
    if(heap->data[left]<heap->data[smallest]) smallest=left;
    if(right<=heap->size&&heap->data[right]<heap->data[smallest]) smallest=right;
    if(smallest!=idx) 
    {
      swap(&heap->data[idx],&heap->data[smallest]);
      idx=smallest;
    }
    else break;
  }
}

void push(MinHeap* heap,ll val)
{
  if(heap->size>=heap->capacity) return ;
  heap->size++;
  heap->data[heap->size]=val;
  heapifyup(heap,heap->size);
}

ll pop(MinHeap* heap)
{
  ll top=heap->data[1];
  heap->data[1]=heap->data[heap->size];
  heap->size--;
  heapifydown(heap,1);
  return top;
}

int main(int argc, char *argv[])
{
  char s[100005];
  fgets(s,sizeof(s),stdin);
  s[strcspn(s,"\n")]='\0';
  int len=strlen(s);
  ll asciilen=(ll)len*8;
  printf("%lld\n",asciilen);
  if(len==0) 
  {
    printf("0\n");
    return 0;
  }
  ll freq[MAX]={0};
  for(int i=0;i<len;i++)
  {
    freq[(int)s[i]]++;
  }
  MinHeap* heap=createHeap(MAX+5);
  int distinct=0;
  for(int i=0;i<MAX;i++)
  {
    if(freq[i]>0)
    {
      push(heap,freq[i]);
      distinct++;
    }
  }
  if(distinct==1)
  {
    printf("%lld\n",(ll)len);
    free(heap->data);
    free(heap);
    return 0;
  }
  ll hufflen=0;
  while(heap->size>1)
  {
    ll a=pop(heap);
    ll b=pop(heap);
    ll sum=a+b;
    hufflen+=sum;
    push(heap,sum);
  }
  printf("%lld\n",hufflen);
  free(heap->data);
  free(heap);
  return 0;
}

小明的衣服

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

#define MAX 100005

typedef long long ll;

typedef struct MinHeap
{
  ll* data;
  int size;
  int capacity;
}MinHeap;

MinHeap* createHeap(int cap)
{
  MinHeap* heap=(MinHeap*)malloc(sizeof(MinHeap));
  heap->data=(ll*)malloc(sizeof(ll)*(cap+1));
  heap->size=0;
  heap->capacity=cap;
  return heap;
}

void swap(ll* a,ll* b)
{
  ll t=*a;
  *a=*b;
  *b=t;
}

void heapifyup(MinHeap* heap,int idx)
{
  while(idx>1&&heap->data[idx]<heap->data[idx/2])
  {
    swap(&heap->data[idx],&heap->data[idx/2]);
    idx=idx/2;
  }
}

void heapifydown(MinHeap* heap,int idx)
{
  while(idx*2<=heap->size)
  {
    int left=idx*2;
    int right=left+1;
    int smallest=idx;
    if(heap->data[left]<heap->data[smallest]) smallest=left;
    if(heap->data[right]<heap->data[smallest]) smallest=right;
    if(smallest!=idx) 
    {
      swap(&heap->data[idx],&heap->data[smallest]);
      idx=smallest;
    }
    else break;
  }
}

void push(MinHeap* heap,ll val)
{
  if(heap->size>=heap->capacity) return ;
  heap->size++;
  heap->data[heap->size]=val;
  heapifyup(heap,heap->size);
}

ll pop(MinHeap* heap)
{
  ll top=heap->data[1];
  heap->data[1]=heap->data[heap->size];
  heap->size--;
  heapifydown(heap,1);
  return top;
}

int main(int argc, char *argv[])
{
  int n;
  scanf("%d",&n);
  ll a[MAX];
  for(int i=0;i<n;i++)
  {
    scanf("%lld",&a[i]);
  }
  if(n==1) 
  {
    printf("0\n");
    return 0;
  }
  MinHeap* heap=createHeap(n);
  for(int i=0;i<n;i++)
  {
    push(heap,a[i]);
  }
  ll total=0;
  while(heap->size>1)
  {
    ll x=pop(heap);
    ll y=pop(heap);
    ll sum=x+y;
    total+=sum;
    push(heap,sum);
  }
  printf("%lld\n",total);
  free(heap->data);
  free(heap);
  return 0;
}

最大差值(平衡二叉树)

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

#define MAX_OPERATIONS 200005

typedef struct Node {
    int val;
    int priority;
    struct Node *left, *right;
} Node;

// 全局变量
Node* root = NULL;
int set_size = 0;

// 创建新节点
Node* createNode(int val) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->val = val;
    newNode->priority = rand();
    newNode->left = newNode->right = NULL;
    return newNode;
}

// 右旋转
Node* rightRotate(Node* y) {
    Node* x = y->left;
    Node* T2 = x->right;
    
    x->right = y;
    y->left = T2;
    
    return x;
}

// 左旋转
Node* leftRotate(Node* x) {
    Node* y = x->right;
    Node* T2 = y->left;
    
    y->left = x;
    x->right = T2;
    
    return y;
}

// 插入节点
Node* insert(Node* root, int val) {
    if (!root) {
        set_size++;
        return createNode(val);
    }
    
    if (val < root->val) {
        root->left = insert(root->left, val);
        if (root->left->priority > root->priority) {
            root = rightRotate(root);
        }
    } else if (val > root->val) {
        root->right = insert(root->right, val);
        if (root->right->priority > root->priority) {
            root = leftRotate(root);
        }
    }
    // 如果值已存在,不插入(根据题目保证不会发生)
    
    return root;
}

// 查找最小值
int findMin(Node* root) {
    if (!root) return -1;
    while (root->left) {
        root = root->left;
    }
    return root->val;
}

// 查找最大值
int findMax(Node* root) {
    if (!root) return -1;
    while (root->right) {
        root = root->right;
    }
    return root->val;
}

// 删除节点
Node* deleteNode(Node* root, int val) {
    if (!root) return NULL;
    
    if (val < root->val) {
        root->left = deleteNode(root->left, val);
    } else if (val > root->val) {
        root->right = deleteNode(root->right, val);
    } else {
        // 找到要删除的节点
        set_size--;
        
        if (!root->left) {
            Node* temp = root->right;
            free(root);
            return temp;
        } else if (!root->right) {
            Node* temp = root->left;
            free(root);
            return temp;
        } else {
            // 有两个子节点,根据优先级旋转
            if (root->left->priority > root->right->priority) {
                root = rightRotate(root);
                root->right = deleteNode(root->right, val);
            } else {
                root = leftRotate(root);
                root->left = deleteNode(root->left, val);
            }
        }
    }
    return root;
}

// 计算权值
int calculateWeight() {
    if (set_size < 1) return -1;
    int min_val = findMin(root);
    int max_val = findMax(root);
    return max_val - min_val;
}

int main() {
    srand(time(0));  // 初始化随机数种子
    
    int Q;
    scanf("%d", &Q);
    
    for (int i = 0; i < Q; i++) {
        int type, x;
        scanf("%d %d", &type, &x);
        
        if (type == 1) {
            // 插入操作
            root = insert(root, x);
        } else {
            // 删除操作
            root = deleteNode(root, x);
        }
        
        // 输出当前权值
        printf("%d\n", calculateWeight());
    }
    
    return 0;
}

最小差值

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

#define MAX_OPERATIONS 200005

typedef struct Node {
    int val;
    int cnt;       // 用于可重集,记录该值出现次数
    int priority;
    struct Node *left, *right;
} Node;

Node* root_val = NULL;   // 存储集合元素
Node* root_diff = NULL;  // 存储相邻差值
int set_size = 0;

// ========== Treap 通用函数 ==========
Node* createNode(int val) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->val = val;
    newNode->cnt = 1;
    newNode->priority = rand();
    newNode->left = newNode->right = NULL;
    return newNode;
}

Node* rightRotate(Node* y) {
    Node* x = y->left;
    Node* T2 = x->right;
    x->right = y;
    y->left = T2;
    return x;
}

Node* leftRotate(Node* x) {
    Node* y = x->right;
    Node* T2 = y->left;
    y->left = x;
    x->right = T2;
    return y;
}

// 插入到 Treap (可重集)
Node* insert(Node* root, int val) {
    if (!root) return createNode(val);
    
    if (val < root->val) {
        root->left = insert(root->left, val);
        if (root->left->priority > root->priority)
            root = rightRotate(root);
    } else if (val > root->val) {
        root->right = insert(root->right, val);
        if (root->right->priority > root->priority)
            root = leftRotate(root);
    } else {
        root->cnt++;  // 重复值,计数增加
    }
    return root;
}

// 删除一个值(可重集)
Node* deleteOne(Node* root, int val) {
    if (!root) return NULL;
    
    if (val < root->val) {
        root->left = deleteOne(root->left, val);
    } else if (val > root->val) {
        root->right = deleteOne(root->right, val);
    } else {
        if (root->cnt > 1) {
            root->cnt--;
        } else {
            if (!root->left) {
                Node* temp = root->right;
                free(root);
                return temp;
            } else if (!root->right) {
                Node* temp = root->left;
                free(root);
                return temp;
            } else {
                if (root->left->priority > root->right->priority) {
                    root = rightRotate(root);
                    root->right = deleteOne(root->right, val);
                } else {
                    root = leftRotate(root);
                    root->left = deleteOne(root->left, val);
                }
            }
        }
    }
    return root;
}

// 查找前驱
int findPrev(Node* root, int val) {
    int prev = -1;
    while (root) {
        if (root->val < val) {
            prev = root->val;
            root = root->right;
        } else {
            root = root->left;
        }
    }
    return prev;
}

// 查找后继
int findNext(Node* root, int val) {
    int next = -1;
    while (root) {
        if (root->val > val) {
            next = root->val;
            root = root->left;
        } else {
            root = root->right;
        }
    }
    return next;
}

// 查找最小值
int findMin(Node* root) {
    if (!root) return -1;
    while (root->left) root = root->left;
    return root->val;
}

// ========== 主要操作 ==========
void insertValue(int x) {
    int prev = findPrev(root_val, x);
    int next = findNext(root_val, x);
    
    if (prev != -1 && next != -1) {
        // 删除旧差值
        root_diff = deleteOne(root_diff, next - prev);
    }
    if (prev != -1) {
        root_diff = insert(root_diff, x - prev);
    }
    if (next != -1) {
        root_diff = insert(root_diff, next - x);
    }
    
    root_val = insert(root_val, x);
    set_size++;
}

void deleteValue(int x) {
    int prev = findPrev(root_val, x);
    int next = findNext(root_val, x);
    
    if (prev != -1) {
        root_diff = deleteOne(root_diff, x - prev);
    }
    if (next != -1) {
        root_diff = deleteOne(root_diff, next - x);
    }
    if (prev != -1 && next != -1) {
        root_diff = insert(root_diff, next - prev);
    }
    
    root_val = deleteOne(root_val, x);
    set_size--;
}

int queryAnswer() {
    if (set_size <= 1) return -1;
    return findMin(root_diff);
}

// ========== 主函数 ==========
int main() {
    srand(time(0));
    
    int Q;
    scanf("%d", &Q);
    
    for (int i = 0; i < Q; i++) {
        int type, x;
        scanf("%d %d", &type, &x);
        
        if (type == 1) {
            insertValue(x);
        } else {
            deleteValue(x);
        }
        
        printf("%d\n", queryAnswer());
    }
    
    return 0;
}

平衡树区间翻转

相关推荐
hanbr几秒前
每日一题day1(Leetcode 76最小覆盖子串)
算法·leetcode
AI科技星2 分钟前
张祥前统一场论中两个电荷定义的统一性解析
开发语言·线性代数·算法·数学建模·平面
代码地平线2 分钟前
C语言实现堆与堆排序详解:从零手写到TopK算法及时间复杂度证明
c语言·开发语言·算法
小江的记录本3 分钟前
【大语言模型】大语言模型——核心概念(预训练、SFT监督微调、RLHF/RLAIF对齐、Token、Embedding、上下文窗口)
java·人工智能·后端·python·算法·语言模型·自然语言处理
炘爚5 分钟前
LeetCode(两两交换链表中的节点)
算法·leetcode·链表
wsoz5 分钟前
Leetcode矩阵-day7
c++·算法·leetcode·矩阵
念越5 分钟前
算法每日一题 Day01|双指针解决移动零问题
java·算法·力扣
不想看见4046 分钟前
Merge k Sorted Lists 优先队列--力扣101算法题解笔记
笔记·算法·leetcode
_深海凉_8 分钟前
LeetCode热题100-合并区间
算法·leetcode·职场和发展
wuweijianlove11 分钟前
算法性能测试中的输入规模与边界影响的技术6
算法