【NOIP2015模拟10.27】魔道研究
来源:互联网 发布:手机中小学课程表软件 编辑:程序博客网 时间:2024/06/09 13:43
题目大意
给你M个操作,每个操作为借来或归还一本编号为Ti,威力值为Pi的魔法书。每次操作之后我们要求求当前魔法书所能弄出的最大威力。最大威力求法:最多选N本书,编号为Ti的书只能取Ti本,把他们加起来。(全是正整数)
N,M,Ti<=300,000 Pi<=
分析
这道题可以稍微把题意变一变,把要解决的问题理清晰:把每个编号Ti的书的威力值前Ti大的书放到一个集合S里,把此集合里前N大的数加起来。
所以用T+1颗线段树维护每个编号及S集合,下标为Pi,动态开区间,用一个数组弄起来。
AC后总结
真是艰难啊,先是想弄一堆堆和2线段树,编程复杂度太大,然而并没有技术含量,我还傻傻的不估计编程复杂度,比赛打到一半弃疗。
这类题都打过,改起来还是辛苦,很多之前出过的错又上来了。错误贴在代码上
#include<cstdio>#include<algorithm>#include<iostream>#define fo(i,j,k) for(i=j;i<=k;i++)#define ll long long using namespace std;const ll N=400005,p=1000000005;struct rec{ ll l,r,cnt,val;}b[30000000];struct re{ ll pos,val;};ll st[N],sst,i,j,dur,ans,n,m,x,y,tt;char ch[20];ll change(ll x,ll l,ll r,ll pos,ll val){ if (!x||!pos) return 0; if (l==r) { b[x].cnt+=val; b[x].val=b[x].cnt*l; //一开始已经知道一位的书本数不止一本,然而val却没有*l,都不知道怎么搞的 return 0; } ll m=(l+r)/2; if (m>=pos) { if (!b[x].l) b[x].l=++tt; change(b[x].l,l,m,pos,val); } else { if (!b[x].r) b[x].r=++tt; change(b[x].r,m+1,r,pos,val); } b[x].cnt=b[b[x].l].cnt+b[b[x].r].cnt; b[x].val=b[b[x].l].val+b[b[x].r].val; return 0;}ll get(ll x,ll l,ll r,ll i,ll j){ if (x==0) return 0; if (l==i&&r==j) return b[x].cnt; ll m=(l+r)/2; if (m>=j) return get(b[x].l,l,m,i,j); else if (m<i) return get(b[x].r,m+1,r,i,j); else return (get(b[x].l,l,m,i,m)+ get(b[x].r,m+1,r,m+1,j));}re get1(ll x,ll l,ll r,ll xth){ re dur={0,0}; if (xth==0) return dur; if (xth>b[x].cnt) { dur.pos=0; dur.val=b[x].val; return dur; } if (l==r) { dur.val=xth*l; dur.pos=l; //完全忘记Xth到这个时候有可能不止1,我之前就打的dur.val=l,然后return,之后改的时候又没想清楚,给.val=l乘b[x].cnt,真是炸了,最后才改对。 } ll m=(l+r)/2; if (b[b[x].r].cnt>=xth) return get1(b[x].r,m+1,r,xth); else { dur=get1(b[x].l,l,m,xth-b[b[x].r].cnt); dur.val+=b[b[x].r].val; return dur; }}int main(){ freopen("grimoire.in","r",stdin); freopen("grimoire.out","w",stdout); scanf("%lld %lld",&n,&m); fo(i,1,m) { if (i==241816) { i=i;//调戏用 } scanf("%s %lld %lld",ch+1,&x,&y); if (ch[1]=='B') { if (st[x]==0) st[x]=++tt; if (get(st[x],1,p,y,p)<x) { if (sst==0) sst=++tt; change(st[x],1,p,y,1); dur=get1(st[x],1,p,x+1).pos;//the x+1 th change(sst,1,p,y,1); change(sst,1,p,dur,-1); } else change(st[x],1,p,y,1); } else { if (get(st[x],1,p,y,p)<=x) { change(st[x],1,p,y,-1); dur=get1(st[x],1,p,x).pos; change(sst,1,p,y,-1); change(sst,1,p,dur,1); } else change(st[x],1,p,y,-1); } dur=get1(sst,1,p,n).val;//一开始所有线段树居然全都维护前X小的了,然而是要降序啊,然后我改了一半成降序的,另一半还是升序,后面耗了好久才改对 printf("%lld\n",get1(sst,1,p,n).val); }}
纵观整个程序,原型是十分失败的,这警示,不能因为“打过,觉得虽然有些生疏也没事”然后细节不想就开打了,因为打题的时候要想别的东西,如果这个时候不想,很有可能到时候就乱打一通了,到头来浪费大量时间,实在是不行。
即使题目看起来很水,也不能找实现难的借口,别人行,怎么自己就不行呢?
时间不是这么用的啊。
0 0
- 【NOIP2015模拟10.27】魔道研究
- [GDOI模拟2016.03.05]魔道研究
- [GDOI模拟2016.03.05]魔道研究
- 魔道研究
- 魔道研究
- JZOJ 4270 魔道研究
- 【NOIP2015 模拟10.27】总结
- NOIP2015模拟1
- NOIP2015模拟3
- NOIP2015模拟2
- NOIP2015模拟4
- 【NOIP2015 模拟9.12】平方和
- 【NOIP2015 10.22模拟】总结
- 【NOIP2015模拟10.20】平均数
- 【NOIP2015模拟10.20】ACM
- 【NOIP2015 10.29模拟】总结
- 【NOIP2015 10.28模拟】总结
- 【NOIP2015 11.3模拟】总结
- java实现快速排序算法
- 机器学习
- hdu5636 BestCoder Round #74 (div.2) 1002 Shortest Path
- Android报错
- ubuntu常用命令(长期更新)
- 【NOIP2015模拟10.27】魔道研究
- HDOJ-2795 Billboard
- 八皇后问题----另类解法
- TCP/IP各个状态
- 一维数组名的本质
- [转载]微服务实战(四):服务发现的可行方案以及实践案例
- Java中的算术运算与关系运算
- Binary Tree Path Sum
- dup与dup2() [转]