Description

“我希望能使用更多的魔法。不对,是预定能使用啦。最终我要被大家称呼为大魔法使。为此我决定不惜一切努力。”
——《The Grimoire of Marisa》雾雨魔理沙
魔理沙一如既往地去帕秋莉的大图书馆去借魔导书(Grimoire) 来学习魔道。
最开始的时候,魔理沙只是一本一本地进行研究。然而在符卡战中,魔理沙还是战不过帕秋莉。
好在魔理沙对自己的借还和研究结果进行了记录,从而发现了那些魔导书的精妙之处。
帕秋莉的那些魔导书,每本都有一个类别编号ti 和威力大小pi。而想要获得最有威力的魔法,就必须同时研究一些魔导书。而研究的这些魔导书就必须要满足,类别编号为T 的书的本数小于等于T,并且总共的本数小于等于一个给定的数N。而研究这些魔导书之后习得的魔法的威力就是被研究的魔导书的威力之和。
为了击败帕秋莉,魔理沙想要利用自己发现的规律来获得最有威力的魔法。
她列出了计划中之后M 次的借还事件,并想要知道每个事件之后自己所能获得的魔法的最大威力。可她忙于魔法材料——蘑菇的收集,于是这个问题就交给你来解决了。

Input

输入文件grimoire.in。
第1 行2 个整数N,M,分别表示魔理沙能研究的魔导书本数的上限和她的借还事件数。
之后M 行,每行的形式为“op t p”(不含引号)。Op 为“BORROW” 或“RETURN”,分别表示借书和还书。T 为一个整数,表示这本书的类别编号。P为一个整数,表示这本书的威力大小。注意,还书时如果有多本书满足类别编号为t,威力大小为p,这表明这些书都是相同的,魔理沙会任选其中一本书还回去。如果你问我为何会有相同的书,多半因为这是魔导书吧。

Output

输出文件grimoire.out。
一共M 行,每行一个整数,即每个事件之后的最大威力。

Sample Input

5 10 
BORROW 1 5811 
BORROW 3 5032
RETURN 3 5032 
BORROW 3 5550 
BORROW 5 3486 
RETURN 1 5811 
RETURN 3 5550 
BORROW 4 5116 
BORROW 3 9563 
BORROW 5 94

Sample Output

5811
10843
5811
11361
14847
9036
3486
8602
18165
18259
 

Data Constraint

对于5% 的数据,1 <= t,N,M <= 50。
对于10% 的数据,1 <= t,N,M <= 100。
对于30% 的数据,1 <= t,N,M<= 10 000。
另有30% 的数据,1 <= p <= 1 000。
对于100% 的数据,1 <= t,N,M <= 300 000,1<= p<= 1 000 000 000。
另外,总共有30% 的数据,满足没有“RETURN” 操作。这部分数据均匀分布。

题目大意:给定t个集合,我们要维护任意区间加入和删除元素,并且把第q区间前q大的元素放在一起维护一个新的集合的前n大

“我们有若干个可重集合,然后我们从第 i 个可重集合中拿前 i 大组成一个新的可重集合 S。我们的目的是动态维护 S 的前 n 大的和。--来自题解

好的,集合第k大的感觉,一开始怀疑是主席树,但是并不是

题解:

显然,我们需要维护所有的小集合以及 S。 维护 maxt 棵权值线段树,第 i 棵线段树对应第 i 个小集合。 我们称这些线段树为小树。 另外维护一棵权值线段树,用来维护 S。我们称这棵线段树为大树。对于 BORROW 操作,我们就是在第 t 棵小树中加入一个元素 p。这个可以通过线段树单点修改完成。 之后,我们要确定要不要将 p 加入 S 中。这个只要知道 p 在第 t 个集合中的排名是否 ≤ t 即可。 加入了 S 以后,我们还要将原来的第 t 大,即现在的第 t+1 大从 S 中删去。对于 RETURN 操作,我们可以类似地,将 BORROW 操作取反即可。而动态维护S前n大的和自然也是小菜一碟了。

需要注意的细节:

①我们区间查找的始终是从大到小的,因此我们在权值线段树上二分的时候要先比较右节点

②val数组维护的是和,而权值在叶子节点上

③权值线段树的空间需求是不能接受的,但动态开点可以解决这个问题

④不要用cin读入字符串,笔者在这儿足足卡了一个小时TLE

⑤S的根节点不能叫n+1,这是一个坑,题目没有说是我浪了,一直20分

官方题解:https://jzoj.net/senior/index.php/main/download/4270/slide.pdf/0/solution_path,不知道能不能打开

#include<iostream>
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std; const int maxn=;
const int Y=;
int n,m,sz,tr;
ll val[maxn*];
int tree[maxn],sum[maxn*];
char c[];
struct TREE
{
int l;int r;
}t[maxn*];
inline int read()
{
char ch=getchar();
int s=,f=;
while (!(ch>=''&&ch<='')) {if (ch=='-') f=-;ch=getchar();}
while (ch>=''&&ch<='') {s=(s<<)+(s<<)+ch-'';ch=getchar();}
return s*f;
}
void update(int &rt,int l,int r,int pos,int z)
{
if (!rt) rt=++sz;
if (!pos) return;
if (l==r)
{
sum[rt]+=z;
val[rt]=sum[rt]*l;
return;
}
int mid=l+r>>;
if (pos<=mid) update(t[rt].l,l,mid,pos,z);
else update(t[rt].r,mid+,r,pos,z);
sum[rt]=sum[t[rt].l]+sum[t[rt].r];
val[rt]=val[t[rt].l]+val[t[rt].r];
return;
}
ll query(int &rt,int l,int r,int ls,int rs)
{
if (!rt) {rt=++sz;return ;}
if (l>=ls&&r<=rs) return sum[rt];
int mid=l+r>>;
int qq=;
if (ls<=mid) qq+=query(t[rt].l,l,mid,ls,rs);
if (rs>mid) qq+=query(t[rt].r,mid+,r,ls,rs);
return qq;
}
int get1(int &rt,int l,int r,int xth)//从大到小第xth个数是多少 pos
{
if (!rt) rt=++sz;
if (!xth) return ;
if (xth>sum[rt]) return ;
if (l==r) return l;
int mid=l+r>>;
if (xth<=sum[t[rt].r]) return get1(t[rt].r,mid+,r,xth);
else return get1(t[rt].l,l,mid,xth-sum[t[rt].r]);
}
ll get2(int &rt,int l,int r,int xth)//后xth个数的值是多少 val
{
if (!rt) rt=++sz;
if (!xth) return ;
if (xth>sum[rt]) return val[rt];
if (l==r) return xth*l*1ll;
int mid=l+r>>;
if (xth<=sum[t[rt].r]) return get2(t[rt].r,mid+,r,xth);
else return get2(t[rt].l,l,mid,xth-sum[t[rt].r])+val[t[rt].r];
}
int main()
{
freopen("grimoire.in","r",stdin);
freopen("grimoire.out","w",stdout);
n=read();m=read();
for (int i=;i<=m;i++)
{
scanf("%s",c);
int t=read(),p=read();
if (c[]=='B'||c[]=='B'||c[]=='B')
{
ll k=query(tree[t],,Y,p,Y);
if (k<t)
{
update(tree[t],,Y,p,);
int pos=get1(tree[t],,Y,t+);
update(tr,,Y,p,);
update(tr,,Y,pos,-);
}
else update(tree[t],,Y,p,);
}
else
{
ll k=query(tree[t],,Y,p,Y);
if (k<=t)
{
update(tree[t],,Y,p,-);
int pos=get1(tree[t],,Y,t);
update(tr,,Y,p,-);
update(tr,,Y,pos,);
}
else update(tree[t],,Y,p,-);
}
ll ans=get2(tr,,Y,n);
printf("%lld\n",ans);
}
return ;
}

[NOIP2015模拟10.27] [JZOJ4270] 魔道研究 解题报告(动态开点+权值线段树上二分)的更多相关文章

  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] 挑竹签 解题报告(拓扑排序)

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

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

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

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

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

  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. jzoj5986. 【WC2019模拟2019.1.4】立体几何题 (权值线段树)

    传送门 题面 题解 不难看出每个点的大小为行列限制中较小的那一个(因为数据保证有解) 对于行的每个限制,能取到的个数是列里限制大于等于它的数的个数,同理,对于列是行里大于它的个数(这里没有等于,为了避 ...

  8. 9 16 模拟赛&关于线段树上二分总结

    1 考试时又犯了一个致命的错误,没有去思考T2的正解而是去简单的推了一下式子开始了漫漫找规律之路,不应该这样做的 为了得到规律虽然也打了暴力 但是还是打了一些不必要的程序 例如求组合数什么的比较浪费时 ...

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

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

随机推荐

  1. HDU 4307 Contest 1

    http://www.cnblogs.com/staginner/archive/2012/08/13/2636826.html 自己看过后两周吧,重新写了一遍.很受启发的.对于0.1,可以使用最小割 ...

  2. ZOJ 3688

    做出这题,小有成就感 本来已打算要用那个禁位的排列公式,可是,问题在于,每个阶乘前的系数r的求法是一个难点. 随便翻了翻那本美国教材<组合数学>,在容斥原理一章的习题里竟有一道类似,虽然并 ...

  3. QQ在线人数统计图数据解析

    转载请注明出处:http://blog.csdn.net/xiaoy_h/article/details/27980851 我相信非常多人一定去过这个地方: http://im.qq.com/onli ...

  4. ValidForm的使用

    1.引入css 请查看下载文件中的style.css,把里面Validform必须部分拷贝到你的css中(文件中这个凝视 "/*==========下面部分是Validform必须的==== ...

  5. Qt Quick 简单介绍

    Qt Quick 是 Qt 提供的一种高级用户界面技术.使用它可轻松地为移动和嵌入式设备创建流畅的用户界面. 在 Android 设备上, Qt Quick 应用默认使用 OpenGL ES ,渲染效 ...

  6. easyui编辑器(kindeditor-4.1.10)

    //1  重写kindedit    -建一个js文件 easyui_kindeditor.js (function ($, K) {     if (!K)         throw " ...

  7. Android-Volley网络通信框架(自己定义Request 请求:实现 GsonRequest)

    1.回想 上篇学习了android 通过 volley 网络通信框架 实现 请求图片的三种方法! 2.重点 (1)复习和熟悉 StringRequest ,JsonObjectRequest 方法 ( ...

  8. IntelliJ IDEA中JAVA连接MYSQL

    1.下载mysql包 2.项目中引入mysql包 3.连接数据库,查询结果 看jdbc数据库连接类 package Facade; import java.sql.*; /** * Created b ...

  9. Codeforces 659F Polycarp and Hay 并查集

    链接 Codeforces 659F Polycarp and Hay 题意 一个矩阵,减小一些数字的大小使得构成一个连通块的和恰好等于k,要求连通块中至少保持一个不变 思路 将数值从小到大排序,按顺 ...

  10. Android VelocityTracker类和Scroller类

    VelocityTracker类:用于跟踪触屏事件的速度,通常使用VelocityTracker的步骤如下: static VelocityTracker obtain():获取一个VelocityT ...