魔道研究

题面

思路

简单的想,就是在 \(T\) 个可重集合每个中选出 \(k\) 个最大的数组成新的可重集合,其中 \(k\) 为其编号

然后在新的集合中选前 \(n\) 大的数,求其和

考虑开 \(T + 1\) 个权值线段树,维护对应的 \(T\) 个可重集合和答案可能在的第 \(T + 1\) 个代表新的集合的线段树

由于空间限制,我们需要动态开点(其实动态开点很简单,线段树二分下去时,遇到一个空节点再使用它。如此一来,在只需开可能使用的节点数)

然后维护区间个数,区间和(注意一个点可能有多个数)

因为是动态开点,所以再记录它的左、右子树的编号

对于 \(B\) 操作,我们直接在根为 \(t\) 的线段树中加入,然后考虑它能不能进入第 \(T + 1\) 棵线段树成为可能的答案。

即查它在第 \(t\) 棵线段树中的从大到小的排名(其实就是求第 \(t\) 棵线段树中 \(p\) 到上限的个数)和)。

如果它的排名 \(\leq t\) ,则可能加入第 \(T + 1\) 个线段树。加入后把现在排名为 \(t+1\) 的数从第 \(T + 1\) 棵线段树中删去(即原先的排名为 \(t\) 的数,它在第 \(T + 1\) 棵线段树中),当然,如果有的话。

对于 \(R\) 操作,就是 \(B\) 操作的逆操作,具体见代码。

\(Code\)

#include<cstdio>
#include<iostream>
using namespace std;
typedef long long LL; const int N = 3e5 , Len = 1e9;
int n , m , tot , len = N + 1;
LL tr[18000005][5]; inline void New(int t , int x){if (!tr[t][x]) tr[t][x] = ++len;} inline void update(int t , int l , int r , int p , int v)
{
tr[t][2] += (LL)v;
tr[t][3] += (LL)p * v;
if (l == r) return;
int mid = (l + r) >> 1;
if (p <= mid)
{
if (!tr[t][0]) New(t , 0);
update(tr[t][0] , l , mid , p , v);
}
else{
if (!tr[t][1]) New(t , 1);
update(tr[t][1] , mid + 1 , r , p , v);
}
} inline int findk(int t , int l , int r , int x , int y)
{
if (l >= x && r <= y) return (int)tr[t][2];
int res = 0 , mid = (l + r) >> 1;
if (x <= mid && tr[tr[t][0]][2]) res += findk(tr[t][0] , l , mid , x , y);
if (y > mid && tr[tr[t][1]][2]) res += findk(tr[t][1] , mid + 1 , r , x , y);
return res;
} inline int kfind(int t , int l , int r , int k)
{
if (l == r) return k <= tr[t][2] ? l : 0;
int mid = (l + r) >> 1;
if (tr[tr[t][1]][2] < k) return kfind(tr[t][0] , l , mid , k - tr[tr[t][1]][2]);
else return kfind(tr[t][1] , mid + 1 , r , k);
} inline LL query(int t , int l , int r , int k)
{
if (l == r) return 1LL * min(1LL * k , tr[t][2]) * l;
int mid = (l + r) >> 1;
LL res = 0;
if (tr[tr[t][1]][2] <= k)
{
res += tr[tr[t][1]][3];
if (tr[tr[t][0]][2] && k > tr[tr[t][1]][2])
res += query(tr[t][0] , l , mid , k - tr[tr[t][1]][2]);
}
else{
if (tr[tr[t][1]][2]) res += query(tr[t][1] , mid + 1 , r , k);
}
return res;
} int main()
{
freopen("grimoire.in" , "r" , stdin);
freopen("grimoire.out" , "w" , stdout);
scanf("%d%d" , &n , &m);
int t , p;
char op[8];
for(register int i = 1; i <= m; i++)
{
int s1 , s2;
scanf("%s%d%d" , op , &t , &p);
if (op[0] == 'B')
{
update(t , 1 , Len , p , 1);
s1 = findk(t , 1 , Len , p , Len);
if (s1 <= t)
{
update(N + 1 , 1 , Len , p , 1);
s2 = kfind(t , 1 , Len , t + 1);
if (s2) update(N + 1 , 1 , Len , s2 , -1);
}
}
else{
s1 = findk(t , 1 , Len , p , Len);
update(t , 1 , Len , p , -1);
if (s1 <= t)
{
update(N + 1 , 1 , Len , p , -1);
s2 = kfind(t , 1 , Len , t);
if (s2) update(N + 1 , 1 , Len , s2 , 1);
}
}
printf("%lld\n" , query(N + 1 , 1 , Len , n));
}
}

JZOJ 4270.【NOIP2015模拟10.27】魔道研究的更多相关文章

  1. JZOJ 4269. 【NOIP2015模拟10.27】挑竹签

    4269. [NOIP2015模拟10.27]挑竹签 (File IO): input:mikado.in output:mikado.out Time Limits: 1000 ms  Memory ...

  2. [NOIP2015模拟10.27] [JZOJ4270] 魔道研究 解题报告(动态开点+权值线段树上二分)

    Description “我希望能使用更多的魔法.不对,是预定能使用啦.最终我要被大家称呼为大魔法使.为此我决定不惜一切努力.”——<The Grimoire of Marisa>雾雨魔理 ...

  3. [jzoj]4271. 【NOIP2015模拟10.27】魔法阵(37种转移的dp)

    题意不说 应该这辈子都不会忘记了... 这是我人生中做的最SB的一道DP题. 真的打的我心态崩了.... 可是竟然被我调出来了..... 也是没谁了... 我们设\(F[i][j][S]\)表示到第\ ...

  4. [NOIP2015模拟10.27] 挑竹签 解题报告(拓扑排序)

    Description 挑竹签——小时候的游戏夏夜,早苗和诹访子在月光下玩起了挑竹签这一经典的游戏.挑竹签,就是在桌上摆上一把竹签,每次从最上层挑走一根竹签.如果动了其他的竹签,就要换对手来挑.在所有 ...

  5. JZOJ 4273. 【NOIP2015模拟10.28B组】圣章-精灵使的魔法语

    4273. [NOIP2015模拟10.28B组]圣章-精灵使的魔法语 (File IO): input:elf.in output:elf.out Time Limits: 1000 ms  Mem ...

  6. JZOJ 4272. 【NOIP2015模拟10.28B组】序章-弗兰德的秘密

    272. [NOIP2015模拟10.28B组]序章-弗兰德的秘密 (File IO): input:frand.in output:frand.out Time Limits: 1000 ms  M ...

  7. [JZOJ 5912] [NOIP2018模拟10.18] VanUSee 解题报告 (KMP+博弈)

    题目链接: https://jzoj.net/senior/#contest/show/2530/2 题目: 众所周知,cqf童鞋对哲学有着深入的理解和认识,并常常将哲学思想应用在实际生活中,例如锻炼 ...

  8. [NOIP2015模拟10.22] 最小代价 解题报告 (最小生成树)

    Description 给出一幅由n个点m条边构成的无向带权图.其中有些点是黑点,其他点是白点.现在每个白点都要与他距离最近的黑点通过最短路连接(如果有很多个黑点,可以选取其中任意一个),我们想要使得 ...

  9. [jzoj 5926] [NOIP2018模拟10.25] naive 的图 解题报告(kruskal重构树+二维数点)

    题目链接: https://jzoj.net/senior/#main/show/5926 题目: 题解: 显然最小的最大路径在最小生成树上(最小生成树=最小瓶颈生成树) 于是我们建出kruskal重 ...

  10. [JZOJ 5893] [NOIP2018模拟10.4] 括号序列 解题报告 (Hash+栈+map)

    题目链接: https://jzoj.net/senior/#main/show/5893 题目: 题解: 考虑暴力怎么做,我们枚举左端点,维护一个栈,依次加入元素,与栈顶元素和栈内第二个元素相同时弹 ...

随机推荐

  1. day02 数据类型 & 运算符

    day02 数据类型 基本数据类型 共有四类八种 1)整数类型 byte short int long ​ byte: 字节 bit比特,1bit = 1二进制位 ,byte占8位 [-128,128 ...

  2. Maven工程提示 java:源值1.5已过时,将在未来所有发行版中删除 出现原因及解决方案(亲测好用)

    原因:Maven工程默认使用Java1.5进行编译,想要不警告,需要在maven的pom文件中进行配置,同时在settings中进行配置 解决方案: <properties> <me ...

  3. 【HBase】简介、结构、数据模型、快速入门部署、shell操作、架构原理、读写数据流程、数据刷写、压缩、分割、Phoenix、表的映射、与hive集成、优化

    一.简介 1.定义 分布式.可扩展.支持海量数据存储的NoSQL数据库 2.数据模型 2.1逻辑结构 2.2物理存储结构 2.3数据模型介绍 Name Space:相当于数据库,包含很多张表 Regi ...

  4. 【离线数仓】Day04-即席查询(Ad Hoc):Presto链接不同数据源查询、Druid建多维表、Kylin使用cube快速查询

    一.Presto 1.简介 概念:大数据量.秒级.分布式SQL查询engine[解析SQL但不是数据库] 架构 不同worker对应不同的数据源(各数据源有对应的connector连接适配器) 优缺点 ...

  5. MongoDB从入门到实战之.NET Core使用MongoDB开发ToDoList系统(2)-Swagger框架集成

    Swagger是什么? Swagger是一个规范且完整API文档管理框架,可以用于生成.描述和调用可视化的RESTful风格的 Web 服务.Swagger 的目标是对 REST API 定义一个标准 ...

  6. LeetCode-02 两数相加(Add Two Numbers)

    描述 给出两个非空的链表用来表示两个非负的整数.其中,它们各自的位数是按照逆序的方式存储的,并且它们的每个节点只能存储一位数字. 如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和. 您 ...

  7. .net core操作MongoDB

    前言 现实中认识的一个搞java(百万富婆)的大佬,已经转行做抖音主播了,搞技术的只能赶在年前再水一篇博客,不足之处欢迎拍砖,以免误人子弟,呔,真是太难受了 环境准备 .net core 3.1 Mo ...

  8. python之路41 前端页面尝试 丑出新高度

    边框 p {/* 左边 */ font-size: 48px; border-left-width: 5px; border-left-style: dotted; /*点点边框*/ border-l ...

  9. 關於scanf()的使用

    要使用scanf函數進行輸入: 1.如果用scanf()要輸入讀取基本變量的值,需要加&. 2.如果用scanf()讀取的是把字符串讀入字符數組中,則不需要加& 1 #include& ...

  10. 基于windows系统使用GNVM进行node切换版本

    GNVM是什么? GNVM 是一个简单的 Windows 下 Node.js 多版本管理器,类似的 nvm nvmw nodist . 安装 进入官网,下载你所需要的包,直达链接 下载完成 放到我们的 ...