当前位置: 首页 > news >正文

UVa1480/LA5034 Jewel

UVa1480/LA5034 Jewel

  • 题目链接
  • 题意
    • 输入格式
    • 输出格式
  • 分析
  • AC 代码

题目链接

  本题是2010年icpc亚洲区域赛天津赛区的J题

题意

  Jimmy买了很多颗大小互不相同的珠子用来穿成项链送给他的女朋友,初始时项链是空的。Jimmy会进行4种操作:

操作说明
Insert x将尺寸为x的珠子穿到项链的尾部
Query_1 s t k查询位置在[s,t]区间中第k小珠子的尺寸
Query_2 x查询当前项链串中尺寸为x的珠子的排名
Query_3 k查询当前项链串中排名为k的珠子的尺寸

输入格式

  多组输入,每组数据第一行是一个整数 N ,表示操作的总数,接下来 N 行每行描述各个操作。每组数据 Insert 总数不超过 100000,Query_1、Query_2 和 Query_3 每类的总数都小于 35000。

输出格式

  对每组数据输出4行,第一行为“Case T:”(其中T是数据的id),接下来 3 行依次是 Query_1、Query_2 和 Query_3 每类的结果总和。

分析

  如果没有Query_1,那么直接用名次树就行了:每次往名次树插入 x 或者查询 kth(k)、rank(x)。为了解决 Query_1 还是要上线段树 ,需要用到“前缀”思想(每个 Insert 操作对应一棵线段树,并且是在前一棵线段树基础上更新得到的),并且按题目交代的数据规模需要动态开点。同名次树一样,线段树每个节点维护其区间内的附加域 size。
  把所有 Insert xix_ixi 操作的 M 个数放到数组里面做一次排序,可以得到每个每个 xix_ixi 的最终位置 p[xi]p[x_i]p[xi],然后再依次处理各个操作:对每个 Insert xix_ixi 初始化其线段树 st[i]st[i]st[i] 为上一棵线段树 st[i−1]st[i-1]st[i1],然后从线段树根结点到 p[xi]p[x_i]p[xi] 所在的叶结点路径上每个结点的 size 做更新(具体来说,根节点 o 对应区间 [1,M],其 size 增加1,记 mid=(1+M)/2mid = (1+M)/2mid=(1+M)/2,若 p[xi]p[x_i]p[xi] 在 [1,mid] 区间,则递归更新左子树 lc[o] —— 对应区间 [1,mid],否则递归更新右子树 rc[o] —— 对应区间 [mid+1,M]);对每个 Query_1 s t k,拿 st[s−1]st[s-1]st[s1]st[t]st[t]st[t] 这两棵线段树做联合查询能得到答案(参见 AC 代码的 kth 方法);对每个 Query_2 x,记当前线段树是第 c 棵, 拿 st[c]st[c]st[c] 做 rank 查询(参见 AC 代码的 rnk 方法);Query_3 k 是 Query_1 的特列(记当前线段树是第 c 棵,则为 Query_1 1 c k)。

AC 代码

#include <iostream>
#include <algorithm>
using namespace std;#define N 103000
#define T 18*N
struct {int e, s, t, x;} op[2*N]; int a[N], st[N], lc[T], rc[T], s[T], m, n, t, kase = 0; char e[8];void update(int& o, int pre, int l, int r, int x) {int m = (l+r)>>1; o = ++t; lc[o] = lc[pre]; rc[o] = rc[pre]; s[o] = s[pre]+1;if (l == r) return;x <= m ? update(lc[o], lc[pre], l, m, x) : update(rc[o], rc[pre], m+1, r, x);
}int kth(int o, int pre, int l, int r, int k) {if (l == r) return a[l];int c = s[lc[o]] - s[lc[pre]], m = (l+r) >> 1;return k <= c ? kth(lc[o], lc[pre], l, m, k) : kth(rc[o], rc[pre], m+1, r, k-c);
}int rnk(int o, int l, int r, int x) {if (l == r) return 1;int m = (l+r)>>1;return x <= m ? rnk(lc[o], l, m, x) : s[lc[o]] + rnk(rc[o], m+1, r, x);
}void solve() {for (int i=m=t=0; i<n; ++i) {cin >> e; op[i].e = e[0]=='I' ? 0 : e[6]-'0';op[i].e == 1 ? cin >> op[i].s >> op[i].t >> op[i].x : cin >> op[i].x;if (op[i].e == 0) a[++m] = op[i].x;}sort(a+1, a+m+1);long long q1 = 0, q2 = 0, q3 = 0;for (int i=0, c=0; i<n; ++i) {if (op[i].e == 0) ++c, update(st[c], st[c-1], 1, m, lower_bound(a+1, a+m+1, op[i].x)-a);else if (op[i].e == 1) q1 += kth(st[op[i].t], st[op[i].s-1], 1, m, op[i].x);else if (op[i].e == 2) q2 += rnk(st[c], 1, m, lower_bound(a+1, a+m+1, op[i].x)-a);else q3 += kth(st[c], st[0], 1, m, op[i].x);}cout << "Case " << ++kase << ':' << endl << q1 << endl << q2 << endl << q3 << endl;
}int main() {ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);st[0] = lc[0] = rc[0] = s[0] = 0;while (cin >> n) solve();return 0;
}
http://www.dtcms.com/a/315292.html

相关文章:

  • webm 读取解析
  • Linux 系统重置用户密码指南
  • go安装gin
  • JMeter 性能测试工具使用教程
  • 【网络运维】Linux:逻辑卷管理
  • Spring @Component注解全解析
  • 计算机网络:子网掩码在路由转发中的关键作用
  • css的选择器
  • 虚拟机中查看和修改文件权限
  • MoonBit Pearls Vol.04:用MoonBit 探索协同式编程
  • Spring Security 认证与授权实现机制
  • 随机森林知识点整理:从原理到实战
  • 课题学习4——将原系统的BERT换为SBERT
  • 【网络运维】Linux:RAID存储技术
  • 单类别目标检测中的 Varifocal Loss 与 mAP 评估:从原理到实践(特别前景和背景类区分)
  • Transformer核心机制:QKV全面解析
  • 图片处理工具类:基于 Thumbnailator 的便捷解决方案
  • Unsloth 大语言模型微调工具介绍
  • 数据结构:反转链表(reverse the linked list)
  • 机器视觉的产品包装帖纸模切应用
  • 深度学习-卷积神经网络CNN-卷积层
  • JMeter的基本使用教程
  • 嵌入式学习之51单片机——串口(UART)
  • STM32F103C8-定时器入门(9)
  • slwl2.0
  • Azure DevOps — Kubernetes 上的自托管代理 — 第 5 部分
  • 05-Chapter02-Example02
  • 微软WSUS替代方案
  • Redis与本地缓存的协同使用及多级缓存策略
  • 【定位设置】Mac指定经纬度定位