树、堆的题目集

星际编码大战

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;
}

平衡树区间翻转

相关推荐
2401_891482172 小时前
C++模块化编程指南
开发语言·c++·算法
暮冬-  Gentle°2 小时前
自定义类型转换机制
开发语言·c++·算法
2301_816651222 小时前
嵌入式C++低功耗设计
开发语言·c++·算法
机器学习之心2 小时前
PSO-LightGBM-ABKDE粒子群算法优化轻量级梯度提升机自适应带宽核密度估计多变量回归区间预测Matlab实现
算法·matlab·回归·abkde·自适应带宽核密度估计·pso-lightgbm·粒子群算法优化轻量级梯度提升机
qq_416018722 小时前
分布式缓存一致性
开发语言·c++·算法
CoovallyAIHub2 小时前
多 Agent 手术推理框架:Agent 辩论+RAG 补上手术知识,零样本超越监督基线 14.6 个百分点
算法·架构·机器人
干啥啥不行,秃头第一名2 小时前
STL容器内部实现剖析
开发语言·c++·算法
Zarek枫煜2 小时前
zig与c3的冒泡排序算法
算法
xiaoye-duck2 小时前
《算法题讲解指南:动态规划算法--简单多状态dp问题》--13.删除并获得点数,14.粉刷房子
c++·算法·动态规划