#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” 操作。这部分数据均匀分布。

#题解
久违的一道数据结构裸题,大家对此垂诞三尺,把此题当做idea题乱搞。
真的好多idea。
有用权值线段树的,有用splay平衡树的,还有的说要n^2过百万的。
额。
然而我看错了题,想出个绝妙的做法,想着ac,实则GG。

那就先讲讲题意。
题意很重要!
有t种书,每次操作在某种书中添加或删除之前加入的某本书。
然后把第i种书中的前i大威力的书加入那个玛丽莎的读书清单内。每次操作结束后回答读书清单中前n大的书的威力之和。
呵呵,这个题意很完整了,应该都看得懂。

那么我们挖掘一下信息,发现,操作分为——加入、删除、查询第k大。
这不就是权值线段树么?

于是乎正解就出来了。

首先,我对于每种书都建立一颗权值线段树,保存的是书在此区间出现的次数和书威力之的和。
这样之我们还需要建立一棵大的权值线段树,也就是保存读书清单。
那么我们对于每次操作,我们直接在每种书中查询修改,然后呢,我们就可以很完美地完成对于每种书的第k大的威力值之和。
于是,我们再去看看大的权值线段树。
假设我们现在新加入一个x威力的书,那么我们对于清单,我设当前选入的点为a1,a2,a3……ai.
若x比ai大,那么在清单中要把ai删除,然后再加入。那么这样就可以很好地搞搞阵啦。

具体如何维护可以看看标程——
都是打完一遍然后copy一遍改改就好了,懒得再打
真·code

uses math;
typenew=recorda:array of int64;end;new1=recorda:array of boolean;end;
vari,j,k,l,n,m,zb,tot,maxx:longint;ans,answer:int64;tree,size,size1,tree1:array[0..13000000] of int64;left,right,root,root1,left1,right1:array[0..13000000] of longint;ch:char;q,wz,last,val,gss,t,p,jl:array[1..300000] of int64;a,b,time,js,xdtree:array[1..300000] of new;
procedure qsort(l,r:longint);
varo,j,m,m1,k:longint;
begino:=l;j:=r;m:=a[i].a[(l+r) div 2];m1:=time[i].a[(l+r) div 2];repeatwhile (a[i].a[o]<m) or ((a[i].a[o]=m) and (time[i].a[o]<m1)) do inc(o);while (a[i].a[j]>m) or ((a[i].a[j]=m) and (time[i].a[j]>m1)) do dec(j);if o<=j thenbegink:=a[i].a[o];a[i].a[o]:=a[i].a[j];a[i].a[j]:=k;k:=time[i].a[o];time[i].a[o]:=time[i].a[j];time[i].a[j]:=k;inc(o);dec(j);end;until o>j;if l<j then qsort(l,j);if r>o then qsort(o,r);
end;
procedure change(var v:longint;l,r:longint;jr,gs:int64);
varmid:longint;
beginif v=0 thenbegininc(tot);v:=tot;end;inc(size1[v],gs);inc(tree1[v],jr*gs);if l=r then exitelsebeginmid:=(l+r) div 2;if jr<=mid then change(left1[v],l,mid,jr,gs)else change(right1[v],mid+1,r,jr,gs);end;
end;
procedure lookfor(v,l,r,k:longint);
varmid:longint;
beginif l=r thenbeginans:=ans+min(k,size1[v])*l;zb:=l;endelsebeginmid:=(l+r) div 2;if size1[right1[v]]>=k then lookfor(right1[v],mid+1,r,k)elsebeginans:=ans+tree1[right1[v]];lookfor(left1[v],l,mid,k-size1[right1[v]]);end;end;
end;procedure insert(var v:longint;l,r:longint;jr,gs:int64);
vari,j,k,mid:longint;
beginif v=0 thenbegininc(tot);v:=tot;end;inc(size[v],gs);inc(tree[v],jr*gs);if l=r then exitelsebeginmid:=(l+r) div 2;if jr<=mid then insert(left[v],l,mid,jr,gs)else insert(right[v],mid+1,r,jr,gs);end;
end;procedure find(v,l,r,k:longint);
varmid:longint;
beginif l=r thenbeginans:=ans+min(k,size[v])*l;zb:=l;endelsebeginmid:=(l+r) div 2;if size[right[v]]>=k then find(right[v],mid+1,r,k)elsebeginans:=ans+tree[right[v]];find(left[v],l,mid,k-size[right[v]]);end;end;
end;
beginassign(input,'grimoire.in');reset(input);assign(output,'grimoire.out');rewrite(output);readln(n,m);i:=0;k:=m;while m>0 dobegininc(i);dec(m);read(ch);if ch='B' thenbeginfor j:=1 to 6 do read(ch);q[i]:=1;readln(t[i],p[i]);maxx:=max(p[i],maxx);endelsebeginfor j:=1 to 6 do read(ch);q[i]:=2;readln(t[i],p[i]);end;end;m:=k;for i:=1 to m dobeginif q[i]=1 thenbeginans:=0;find(root[t[i]],0,maxx,t[i]);insert(root[t[i]],0,maxx,p[i],1);if p[i]>=zb thenbeginchange(root1[0],0,maxx,p[i],1);change(root1[0],0,maxx,zb,-1);end;ans:=0;lookfor(root1[0],0,maxx,n);jl[i]:=ans;endelseif q[i]=2 thenbeginans:=0;find(root[t[i]],0,maxx,t[i]+1);insert(root[t[i]],0,maxx,p[i],-1);if p[i]>=zb thenbeginchange(root1[0],0,maxx,p[i],-1);change(root1[0],0,maxx,zb,1);end;ans:=0;lookfor(root1[0],0,maxx,n);jl[i]:=ans;endend;for i:=1 to m do writeln(jl[i]);
end.

你以为完了吗?
不,我还要给那么讲讲我的错误理解的做法打了两个小时:
再看看题意:
有t种书,每次操作在某种书中添加或删除之前加入的某本书。
然后把第i种书中的前i大威力的书加入那个玛丽莎的读书清单内。
考虑删掉: 每次操作结束后回答读书清单中前n大的书的威力之和。
那么这题发现就是到sb题。
但是,我们可以用二分加线段树搞搞,好像比权值线段树好想、好写得多。
只是多想+多写了1个小时罢了
代码量惊人!

各位还是回避把,这个留给我面壁。

uses math;
typenew=recorda:array of int64;end;new1=recorda:array of boolean;end;
vari,j,n,m:longint;l,r,k,mid,answer,ans,gs,da,sum,maxx:int64;q,t,p,wz,last:array[1..300000] of int64;kk:array[1..300000] of boolean;a,b,time,js,tree,size:array[1..300000] of new;bz:array[1..300000] of new1;ch:char;
procedure insert(i,x,l,r,st,value,value1:longint);
varm:longint;
beginif (l=r) thenbegintree[i].a[x]:=value;size[i].a[x]:=value1;endelsebeginm:=(l+r)shr 1;if st<=m then insert(i,2*x,l,m,st,value,value1);if st>m then insert(i,2*x+1,m+1,r,st,value,value1);tree[i].a[x]:=tree[i].a[x*2]+tree[i].a[x*2+1];size[i].a[x]:=size[i].a[x*2]+size[i].a[x*2+1];end;
end;
procedure look_for(i,x,l,r,st,en:longint);
varm:longint;
beginif (l=st)and(r=en) thenbeginans:=ans+size[i].a[x];answer:=answer+tree[i].a[x];endelsebeginm:=(l+r)shr 1;if en<=m then look_for(i,2*x,l,m,st,en)else if st>m then look_for(i,2*x+1,m+1,r,st,en)elsebeginlook_for(i,2*x,l,m,st,m);look_for(i,2*x+1,m+1,r,m+1,en);end;end;
end;
procedure qsort(l,r:longint);
varo,j,m,m1,k:longint;
begino:=l;j:=r;m:=a[i].a[(l+r) div 2];m1:=time[i].a[(l+r) div 2];repeatwhile (a[i].a[o]<m) or ((a[i].a[o]=m) and (time[i].a[o]<m1)) do inc(o);while (a[i].a[j]>m) or ((a[i].a[j]=m) and (time[i].a[j]>m1)) do dec(j);if o<=j thenbegink:=a[i].a[o];a[i].a[o]:=a[i].a[j];a[i].a[j]:=k;k:=time[i].a[o];time[i].a[o]:=time[i].a[j];time[i].a[j]:=k;inc(o);dec(j);end;until o>j;if l<j then qsort(l,j);if r>o then qsort(o,r);
end;
beginassign(input,'grimoire.in');reset(input);assign(output,'grimoire.out');rewrite(output);readln(n,m);i:=0;k:=m;while m>0 dobegininc(i);dec(m);read(ch);if ch='B' thenbeginfor j:=1 to 6 do read(ch);q[i]:=1;readln(t[i],p[i]);maxx:=max(t[i],maxx);endelsebeginfor j:=1 to 6 do read(ch);q[i]:=2;readln(t[i],p[i]);end;end;for i:=1 to maxx dobeginsetlength(a[i].a,1);setlength(b[i].a,1);end;m:=k;for i:=1 to m dobeginif q[i]=1 thenbegininc(a[t[i]].a[0]);setlength(a[t[i]].a,a[t[i]].a[0]+1);a[t[i]].a[a[t[i]].a[0]]:=p[i];setlength(time[t[i]].a,a[t[i]].a[0]+1);time[t[i]].a[a[t[i]].a[0]]:=i;endelsebegininc(b[t[i]].a[0]);setlength(b[t[i]].a,b[t[i]].a[0]+1);b[t[i]].a[b[t[i]].a[0]]:=p[i];setlength(js[t[i]].a,b[t[i]].a[0]+1);js[t[i]].a[b[t[i]].a[0]]:=i;end;end;for i:=1 to maxx dobeginsetlength(bz[i].a,a[i].a[0]+1);for j:=1 to a[i].a[0] do bz[i].a[j]:=true;end;for i:=1 to maxx dobeginif a[i].a[0]>0 thenbeginqsort(1,a[i].a[0]);end;end;for i:=1 to maxx dobeginfor j:=1 to a[i].a[0] dobeginwz[time[i].a[j]]:=j;end;end;for i:=1 to maxx dobeginfor j:=1 to b[i].a[0] dobeginl:=1;r:=a[i].a[0];while l<=r dobeginmid:=(l+r) div 2;if a[i].a[mid]>=b[i].a[j] thenbeginr:=mid-1;answer:=mid;endelsebeginl:=mid+1;end;end;while (bz[i].a[answer]) and (answer>1) and (a[i].a[answer-1]=a[i].a[answer]) do dec(answer);while (not bz[i].a[answer]) and (answer<a[i].a[0]) and (a[i].a[answer+1]=a[i].a[answer]) do inc(answer);bz[i].a[answer]:=false;wz[js[i].a[j]]:=answer;end;end;for i:=1 to maxx dobeginsetlength(tree[i].a,1);tree[i].a[0]:=a[i].a[0]*4;setlength(tree[i].a,tree[i].a[0]+1);setlength(size[i].a,1);size[i].a[0]:=a[i].a[0]*4;setlength(size[i].a,size[i].a[0]+1);end;for i:=1 to m dobeginif q[i]=1 thenbegings:=a[t[i]].a[0];insert(t[i],1,1,gs,wz[i],p[i],1);l:=1;r:=gs;while l<=r dobeginmid:=(l+r) div 2;answer:=0;ans:=0;look_for(t[i],1,1,gs,mid,gs);if ans<t[i] thenbeginr:=mid-1;endelseif ans>t[i] thenbeginl:=mid+1;endelseif ans=t[i] thenbeginbreak;end;end;sum:=sum-last[t[i]]+answer;writeln(sum);last[t[i]]:=answer;endelsebegings:=a[t[i]].a[0];insert(t[i],1,1,gs,wz[i],0,0);l:=1;r:=gs;while l<=r dobeginmid:=(l+r) div 2;answer:=0;ans:=0;look_for(t[i],1,1,gs,mid,gs);if ans<t[i] thenbeginr:=mid-1;endelseif ans>t[i] thenbeginl:=mid+1;endelseif ans=t[i] thenbeginbreak;end;end;sum:=sum-last[t[i]]+answer;writeln(sum);last[t[i]]:=answer;end;end;
end.

转载于:https://www.cnblogs.com/RainbowCrown/p/11148410.html

2018.07.12【2018提高组】模拟B组 【NOIP2015模拟10.27】魔道研究相关推荐

  1. jzoj4270 [NOIP2015模拟10.27]魔道研究 线段树

    Description "我希望能使用更多的魔法.不对,是预定能使用啦.最终我要被大家称呼为大魔法使.为此我决定不惜一切努力." --<The Grimoire of Mar ...

  2. 网吧服务器全部进不了系统,2018.07.12某网吧因为服务器系统盘健康度导致全体卡死重启的故障分析处理过程...

    原标题:2018.07.12某网吧因为服务器系统盘健康度导致全体卡死重启的故障分析处理过程 导读: 天晚上20:54接到某网吧电话,说整个网吧大部分电脑自动重启了,而且进不去系统了.立即用电脑远程登录 ...

  3. 2018.07.12【2018提高组】模拟B组 【NOIP2015模拟10.27】魔法阵

    #Description 帕秋莉·诺蕾姬,有着"不动的大图书馆" 的称号,擅长使用各种各样的属性魔法. --<东方求闻史记> 一如既往地,帕秋莉在图书馆中研究着魔法.今 ...

  4. 嵌入式 Linux 开发工具篇问题整理//C语言测试(杨辉三角、递归调用实现阶乘、计算器、统计字符串出现次数)//2018.07.12.//

    嵌入式 Linux 开发工具篇问题整理 1. 嵌入式开发与传统开发的区别?(同类问题:单片机开发与嵌入式开发的区别)             是否有无操作系统:     2. 移植操作系统的好处有哪些 ...

  5. 【一周头条盘点】中国软件网(2018.11.12~2018.11.16)

    每一个企业级应用的人都置顶了中国软件网 中国软件网为你带来最新鲜的行业干货 一周热点 华为获得全球首个微模块产品PUE测试证书 近日,第四届数据中心基础设施峰会在西安成功召开,会上,TGG(中国)副主 ...

  6. 【跃迁之路】【522天】程序员高效学习方法论探索系列(实验阶段279-2018.07.12)...

    @(跃迁之路)专栏 [跃迁之路]奖励金计划正式开始 从2018.7.1起,[跃迁之路]奖励金计划正式起航,从今以后,每月1日,我会将自己个人上月收入的1%计入[跃迁之路]奖励金池,积累到足够金额后,将 ...

  7. JZOJ2018.07.12【2018提高组】模拟B组 魔道研究

    4270. [NOIP2015模拟10.27]魔道研究 题目描述 "我希望能使用更多的魔法.不对,是预定能使用啦.最终我要被大家称呼为大魔法使.为此我决定不惜一切努力." --&l ...

  8. JZOJ2018.07.12【2018提高组】模拟B组 挑竹签

    4269. [NOIP2015模拟10.27]挑竹签 题目描述 挑竹签--小时候的游戏 夏夜,早苗和诹访子在月光下玩起了挑竹签这一经典的游戏. 挑竹签,就是在桌上摆上一把竹签,每次从最上层挑走一根竹签 ...

  9. 2018.12.08【NOIP提高组】模拟B组总结(未完成)

    2018.12.08[NOIP提高组]模拟B组总结 diyiti 保留道路 进化序列 B diyiti Description 给定n 根直的木棍,要从中选出6 根木棍,满足:能用这6 根木棍拼出一个 ...

最新文章

  1. Google公布OpenFermion:量子计算机的开源软件包
  2. python正则_Python基础12之Python正则
  3. TCP/IP拥塞控制复习
  4. matplotlib包的学习(二)
  5. 高度平衡的二叉搜索树基础概念与经典题目(Leetcode题解-Python语言)
  6. Taro+react开发(97):问答模块04
  7. matlab暂态信号,MATLAB6在电力暂态波形仿真实现中的应用
  8. Flex之嵌入外部资源
  9. 使用xmodmap修改键盘映射
  10. Funcode拍飞虫 C语言
  11. 使用vue+HBulider云游戏接口开发单击斗地主网页版
  12. redis-狂神基础版
  13. Revel模板引擎Template基本语法
  14. 战略规划,要这么做才对!
  15. ubuntu10.10下smbd服务配置——实现主机WinXP与虚拟机Ubuntu10.10共享
  16. dedecms 织梦后台系统配置参数空白的解决方法
  17. Icon glyphs 小图标命名收藏
  18. 将png图片转化为icon
  19. 如何删除CSDN自己上传的资源(2021年12月29亲测有效)
  20. 最小公倍数和最大公约数 (__gcd(x,y) )

热门文章

  1. 常用的相似性度量算法
  2. Mac 3D艺术字一键生成工具:​​​​Art Text
  3. C盘系统下常见的系统目录
  4. java计算机毕业设计同学录管理系统源码+系统+数据库+lw文档+mybatis+运行部署
  5. 前端 + 后端 实现分片上传(断点续传/极速秒传)
  6. iOS 中的 timer 任务(寻找内存恶鬼之旅)
  7. 银行业务管理软件 (1)
  8. IT历史:浏览器发展历史
  9. DATEDIF函数实例
  10. MySQL语句练习50题