[GDOI模拟2016.03.05]魔道研究
2016-03-07 18:38
239 查看
Description
给出T个集合,和m个操作,一开始所有集合皆为空。每个操作有两种形式,一是在t集合里加入一个元素x,一种是在t集合里删除一个元素x(保证x存在)。然后从每个集合t中选出前t大的元素加入另一个大集合s中,求s中的前n大元素和。
m,n,t≤300000,所有元素都为不大于109的正整数。
Solution
很明显的数据结构题,关键是要如何维护。想到区间前k大,马上就想到了主席树这种神奇的东西。然而这道题带修改!仔细观察发现其实并不需要主席树的前缀和模式,所以把主席树中的每一颗树分开来就行了。每次操作在单独的一棵线段树上修改。然后判断这个操作对前K大有没有影响,如果有影响就在总的那棵线段树上修改,然后就能过了。
注意动态开节点。
Code
给出T个集合,和m个操作,一开始所有集合皆为空。每个操作有两种形式,一是在t集合里加入一个元素x,一种是在t集合里删除一个元素x(保证x存在)。然后从每个集合t中选出前t大的元素加入另一个大集合s中,求s中的前n大元素和。
m,n,t≤300000,所有元素都为不大于109的正整数。
Solution
很明显的数据结构题,关键是要如何维护。想到区间前k大,马上就想到了主席树这种神奇的东西。然而这道题带修改!仔细观察发现其实并不需要主席树的前缀和模式,所以把主席树中的每一颗树分开来就行了。每次操作在单独的一棵线段树上修改。然后判断这个操作对前K大有没有影响,如果有影响就在总的那棵线段树上修改,然后就能过了。
注意动态开节点。
Code
[code]#include<cstdio> #include<cstring> #include<algorithm> #define fo(i,a,b) for(int i=a;i<=b;i++) #define maxt 1000000007 #define N 300005 #define ll long long using namespace std; struct note{ int tot,l,r;ll sum; }t[N*92]; int root ,n,m,x,y,k,tot; ll ans; char s[6]; void add(int &v,int l,int r,int x,int y) { if (!v) v=++tot; t[v].sum+=x*y;t[v].tot+=y; if (l==r) return; int m=(l+r)/2; if (x<=m) add(t[v].l,l,m,x,y); else add(t[v].r,m+1,r,x,y); } void find(int v,int l,int r,int x) { if (l==r) {k=l;return;} int m=(l+r)/2; if (t[t[v].r].tot>=x) find(t[v].r,m+1,r,x); else find(t[v].l,l,m,x-t[t[v].r].tot); } void getans(int v,int l,int r,int x) { if (l==r) {ans+=min(x,t[v].tot)*l;return;} int m=(l+r)/2; if (t[t[v].r].tot>=x) getans(t[v].r,m+1,r,x); else ans+=t[t[v].r].sum,getans(t[v].l,l,m,x-t[t[v].r].tot); } int main() { scanf("%d%d",&n,&m); fo(i,1,m) { scanf("%s%d%d",s,&x,&y); if (s[0]=='B') { if (t[root[x]].tot>=x) find(root[x],1,maxt,x); else k=0; if (y>=k) { add(root[0],1,maxt,y,1); if (k) add(root[0],1,maxt,k,-1); } add(root[x],1,maxt,y,1); } else { if (t[root[x]].tot>x) find(root[x],1,maxt,x+1); else k=0; if (y>=k) { add(root[0],1,maxt,y,-1); if (k) add(root[0],1,maxt,k,1); } add(root[x],1,maxt,y,-1); } ans=0;getans(root[0],1,maxt,n); printf("%lld\n",ans); } }
相关文章推荐
- poj1161Post Office【经典dp】
- 工作中遇到的遇到的问题总结20160307
- Pro Git中文版——分布式 Git
- IOS 成员变量,全局变量,局部变量定义,static与extern的区别
- SQL语句执行效率优化
- 在学习过程中总结的LoaderManager的LoaderCallbacks刷新数据以使onLoadFinished回调方法能被执行的两种方式
- YTU 1055: 输入字符串以及输出
- 【JavaScript】JS中String的split()活用
- [置顶] 资产组合优化原理与实例 Portfolio Optimization
- STL与泛型编程<五>:Sets和Multisets
- 算法补习-第六天-查找(下)
- hihocoder-1186-求约数
- JSON和JSONP JSONP 实现跨域访问
- Pro Git中文版——服务器上的 Git
- 634A.Island Puzzle
- 二柱子问题(随机产生四则运算题目)
- mysql 联结查询
- Pro Git 中文版——Git 分支
- Android中关于SimpleAdapter的简单理解
- 树莓派: raspberry pi 和电脑直连 (无显示器,无路由器,无USB wifi)