[BZOJ3932] [CQOI2015]任务查询系统(主席树 || 树状数组 套 主席树 + 差分 + 离散化)
看到这个题有个很暴力的想法,
可以每一个时间点都建一颗主席树,主席树上叶子节点 i 表示优先级为 i 的任务有多少个。
当 x 到 y 有个优先级为 k 的任务时,循环 x 到 y 的每个点,都插入一个 k。
当然这样肯定完蛋。
x 到 y 插入一个优先级为 k 的任务?
想到差分,给时间点为 x 的主席树插入 k,给时间点为 y + 1 的主席树插入 -k。
那么求一个树状数组的前缀和就好了。
前缀和?
用树状数组优化。
这样就可以用 树状数组 套 主席树 来做。
——代码
#include <cstdio>
#include <iostream>
#include <algorithm>
#define LL long long const int MAXN = 1e5 + , p = ;
int n, m, cnt, t;
int S[MAXN], E[MAXN], P[MAXN], num[MAXN], root[MAXN], id[MAXN], q[], s[MAXN * p], ls[MAXN * p], rs[MAXN * p];
LL sum[MAXN * p], pre = ; inline int read()
{
int x = , f = ;
char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -;
for(; isdigit(ch); ch = getchar()) x = (x << ) + (x << ) + ch - '';
return x * f;
} inline bool cmp(int x, int y)
{
return P[x] < P[y];
} inline void insert(int last, int &now, int l, int r, int x, int v1, int v2)
{
if(!now) now = ++cnt;
sum[now] = sum[last] + v1, s[now] = s[last] + v2, ls[now] = ls[last], rs[now] = rs[last];
if(l == r) return;
int mid = (l + r) >> ;
if(x <= mid) insert(ls[last], ls[now], l, mid, x, v1, v2);
else insert(rs[last], rs[now], mid + , r, x, v1, v2);
} inline LL query(int l, int r, int k)
{
if(l == r)
{
LL t2 = ;
for(int i = ; i <= t; i++) t2 += sum[q[i]];
return t2;
}
LL t2 = ;
int t1 = , mid = (l + r) >> ;
for(int i = ; i <= t; i++) t1 += s[ls[q[i]]], t2 += sum[ls[q[i]]];
if(k <= t1)
{
for(int i = ; i <= t; i++) q[i] = ls[q[i]];
return query(l, mid, k);
}
else
{
for(int i = ; i <= t; i++) q[i] = rs[q[i]];
return t2 + query(mid + , r, k - t1);
}
} int main()
{
int i, j, x, a, b, c;
LL k;
n = read();
m = read();
for(i = ; i <= n; i++)
{
S[i] = read();
E[i] = read();
P[i] = read();
id[i] = i;
}
std::sort(id + , id + n + , cmp);
for(i = ; i <= n; i++) num[id[i]] = i;
for(i = ; i <= n; i++)
{
for(j = S[i]; j <= n; j += j & -j) insert(root[j], root[j], , n, num[i], P[i], );
for(j = E[i] + ; j <= n; j += j & -j) insert(root[j], root[j], , n, num[i], -P[i], -);
}
for(i = ; i <= m; i++)
{
scanf("%d %d %d %d", &x, &a, &b, &c);
k = + (LL)(a * pre + b) % c;
t = ;
for(j = x; j; j -= j & -j) q[++t] = root[j];
pre = query(, n, k);
printf("%lld\n", pre);
}
return ;
}
其实如果按照时间排序的话,依次插入主席树,就可以维护前缀和,而省去了树状数组的麻烦。
然后注意的是每个时间点有可能会有多颗主席树。
——代码
#include <cstdio>
#include <iostream>
#include <algorithm>
#define LL long long const int MAXN = 1e5 + ;
int n, m, tot, size, cnt;
int num[MAXN], id[MAXN], v[MAXN], ls[MAXN * ], rs[MAXN * ], s[MAXN * ], root[MAXN];
LL pre = , sum[MAXN * ];
struct node
{
int S, val, type, num;
}p[MAXN * ]; inline int read()
{
int x = , f = ;
char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -;
for(; isdigit(ch); ch = getchar()) x = (x << ) + (x << ) + ch - '';
return x * f;
} inline bool cmp(node x, node y)
{
return x.S < y.S;
} inline void insert(int &now, int l, int r, int x, int v1, int v2)
{
++cnt;
sum[cnt] = sum[now] + v1;
s[cnt] = s[now] + v2;
ls[cnt] = ls[now];
rs[cnt] = rs[now];
now = cnt;
if(l == r) return;
int mid = (l + r) >> ;
if(x <= mid) insert(ls[now], l, mid, x, v1, v2);
else insert(rs[now], mid + , r, x, v1, v2);
} inline LL query(int now, int l, int r, int x)
{
if(l == r) return sum[now];
int mid = (l + r) >> ;
if(x <= s[ls[now]]) return query(ls[now], l, mid, x);
else return sum[ls[now]] + query(rs[now], mid + , r, x - s[ls[now]]);
} inline bool cmp1(int x, int y)
{
return v[x] < v[y];
} int main()
{
int i, j, x, y, z, a;
LL k;
n = read();
m = read();
for(i = ; i <= n; i++)
{
x = read();
y = read();
v[i] = read();
num[i] = i;
p[++tot].S = x, p[tot].val = v[i], p[tot].type = ;
p[++tot].S = y + , p[tot].val = -v[i], p[tot].type = -;
}
std::sort(num + , num + n + , cmp1);
for(i = ; i <= n; i++) id[num[i]] = i;
/*std::sort(v + 1, v + n + 1);
size = std::unique(v + 1, v + n + 1) - (v + 1);
for(i = 1; i <= n; i++) id[i] = std::lower_bound(v + 1, v + size + 1, id[i]) - v;*/
tot = ;
for(i = ; i <= n; i++) p[++tot].num = id[i], p[++tot].num = id[i];
std::sort(p + , p + tot + , cmp);
j = ;
for(i = ; i <= m; i++)
{
root[i] = root[i - ];
while(p[j].S == i)
insert(root[i], , n, p[j].num, p[j].val, p[j].type), j++;
}
for(i = ; i <= m; i++)
{
a = read();
x = read();
y = read();
z = read();
k = + (LL)(x * pre + y) % z;
printf("%lld\n", pre = query(root[a], , n, k));
}
return ;
}
最后,需要注意对动态开点的理解。
以及,这个题是对优先级离散化,优先级有可能有相同的,但是离散化却不去重,这就会使得相同数值会是递增的一段数。
为什么不去重?
这是为了方便找前 k 个。
如果去重,有可能 query 时,找到一个叶子节点它的个数会超过一个,比如说 5 个,而只要找 3 个,那样处理就比较麻烦,还得再记录每个叶子节点的优先级。
不去重就保证了每个叶节点的个数只有一个,而对于答案没有影响。
[BZOJ3932] [CQOI2015]任务查询系统(主席树 || 树状数组 套 主席树 + 差分 + 离散化)的更多相关文章
- BZOJ3932 CQOI2015 任务查询系统 【主席树】
BZOJ3932 CQOI2015 任务查询系统 Description 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的任务用三元组(Si,Ei, ...
- [COGS257]动态排名系统 树状数组套主席树
257. 动态排名系统 时间限制:5 s 内存限制:512 MB [问题描述]给定一个长度为N的已知序列A[i](1<=i<=N),要求维护这个序列,能够支持以下两种操作:1.查询A[ ...
- bzoj1901--树状数组套主席树
树状数组套主席树模板题... 题目大意: 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]--a[ ...
- BZOJ 3196 Tyvj 1730 二逼平衡树 ——树状数组套主席树
[题目分析] 听说是树套树.(雾) 怒写树状数组套主席树,然后就Rank1了.23333 单点修改,区间查询+k大数查询=树状数组套主席树. [代码] #include <cstdio> ...
- BZOJ 1901 Zju2112 Dynamic Rankings ——树状数组套主席树
[题目分析] BZOJ这个题目抄的挺霸气. 主席树是第一时间想到的,但是修改又很麻烦. 看了别人的题解,原来还是可以用均摊的思想,用树状数组套主席树. 学到了新的姿势,2333o(* ̄▽ ̄*)ブ [代 ...
- BZOJ1901 - Dynamic Rankings(树状数组套主席树)
题目大意 给定一个有N个数字的序列,然后又m个指令,指令种类只有两种,形式如下: Q l r k 要求你查询区间[l,r]第k小的数是哪个 C i t 要求你把第i个数修改为t 题解 动态的区间第k ...
- BZOJ_3196_Tyvj 1730 二逼平衡树_树状数组套主席树
BZOJ_3196_Tyvj 1730 二逼平衡树_树状数组套主席树 Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排 ...
- ZOJ 2112 Dynamic Rankings(树状数组套主席树 可修改区间第k小)题解
题意:求区间第k小,节点可修改 思路:如果直接用静态第k小去做,显然我更改一个节点后,后面的树都要改,这个复杂度太高.那么我们想到树状数组思路,树状数组是求前缀和,那么我们可以用树状数组套主席树,求出 ...
- P2617 Dynamic Rankings(树状数组套主席树)
P2617 Dynamic Rankings 单点修改,区间查询第k大 当然是无脑树套树了~ 树状数组套主席树就好辣 #include<iostream> #include<cstd ...
随机推荐
- lock to deteck in oracle
0,5,10 0-23 * * * /home/oracle/utility/blocker/detect_blocker.sh db 120 > /home/oracle/utility/tr ...
- 12.1Java-构造方法
一.构造方法 作用:在new的同时对成员变量赋值,给对象的属性初始化赋值格式:权限 方法名(参数列表){}方法的名字,必须和类的名字完全一致,大小写一致构造方法不许写返回值类型,如void,int 构 ...
- 调用wsdl接口,参数是xml格式
1.最近太累了,好困.闲话少许直奔主题吧.上代码 try{ String wsurl = "http://172.16.16.236:9999/xxx/ws/WSService?wsdl&q ...
- opencv4android移植到系统app
最近在尝试使用opencv4android实现投影仪的自动对焦功能,在AndroidStudio后需要将功能移到系统工程编译成系统app,仅以此文记录下移植过程中遇到的问题. 首先去opencv官网下 ...
- Farseer.net轻量级ORM开源框架 V1.x 入门篇:数据库配置文件
导航 目 录:Farseer.net轻量级ORM开源框架 目录 上一篇:Farseer.net轻量级ORM开源框架 V1.x 入门篇:新版本说明 下一篇:Farseer.net轻量级ORM开源框架 ...
- VC++模拟一次鼠标点击返回原位置
HWND h; RECT r1; POINT p;//x,y void ONCE() { h=::FindWindow(NULL,"biaoti"); ::GetWindowRec ...
- zabbix3.0.4 部署之八 (zabbix3.0.4 报警前端配置)
(如何让报警信息推送----微信.邮件)(邮件与微信一样就不在重复) 创建一个用户 将用户加入administrator组 添加之前设置的报警媒介脚本 设置报警等级 创建动作 配置报警内容 设置报警条 ...
- Eureka 整理
服务治理:(该模块也可以使用集群) 该模块主要负责完成微服务架构中的服务治理功能. 1.构建服务注册中心. 每个服务单元需要向注册中心登记自己提供的服务. 2.服务注册与服务发现. 服务之间的调用不再 ...
- anchor_target_layer层其他部分解读
inds_inside = np.where( (all_anchors[:, 0] >= -self._allowed_border) & (all_anchors[:, 1] > ...
- 关于Maven项目的pom.xml中的依赖或插件失效的解决方法
1.请将<dependency>标签包含的依赖从<dependencyManagement>中拿出来,单独放在<dependencies>标签里面.2.请将< ...