博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hdu4288 Coder(段树+分离)
阅读量:7041 次
发布时间:2019-06-28

本文共 2513 字,大约阅读时间需要 8 分钟。

主题链接:

题意:

题目中给了三个操作
1:add x 就是把x插进去 
2:delete x 就是把x删除
3:sum 就是求下标%5=3的元素的和。
另一个条件是插入和删除最后都要保证数列有序。

。。

首先告诉一种暴力的写法。

。由于时间很充足,须要对stl里面的函数有所了解。

就是直接申明一个vector的容器。然后直接用vector里面的操作比方 insert,erase等等操作。

。只是这个效率非常低。。

最后跑出来6000多ms。

。(强哥的代码)

代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define eps 1e-9#define ll long long#define INF 0x3f3f3f3fusing namespace std;char s[5];int n;vector
a;int main(){ int len,val; vector
::iterator iter; while(cin>>n) { len=0; a.clear(); while(n--) { scanf("%s",s); if(s[0]=='s') { long long ans = 0; for(int i=2; i < len ; i+=5) ans += a[i]; cout<
<
另外一种方法是线段树做法,这个要维护5颗线段树。结构体里面保存每一个节点的个数。首先由于线段树不支持插入,删除,要维护一个个数cnt,当插入一个数的时候,你看原来%3的数,如今取余肯定等于2,那么怎么办呢??那么这个cnt就起到了奇妙的作用。每当插入删除的时候就把对应的节点数变化,来维护那5棵线段树。

最后由于没有告诉数据范围,所以要採取离散化,然后离线处理,最后得出全部要操作的总个数,然后依此建树。第一次用离散化,认为好高大上。。。

代码:(參考自cxlove)
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define eps 1e-9#define ll long long#define INF 0x3f3f3f3fusing namespace std;const int maxn=100000+10;int n,a[maxn],b[maxn];char op[maxn][5];struct Tree{ int cnt; ll sum[5];}tree[maxn<<2];void buildtree(int l,int r,int dex){ tree[dex].cnt=0; memset(tree[dex].sum,0,sizeof(tree[dex].sum)); if(l==r) return; int mid=(l+r)>>1; buildtree(l,mid,dex<<1); buildtree(mid+1,r,dex<<1|1);}void push_up(int dex){ for(int i=0;i<5;i++) tree[dex].sum[i]=tree[dex<<1].sum[i]+tree[dex<<1|1].sum[((i-tree[dex<<1].cnt)%5+5)%5];}void update(int l,int r,int dex,int pos,int flag,int val){ tree[dex].cnt+=flag; if(l==r) { if(flag==1) tree[dex].sum[1]=val; else tree[dex].sum[1]=0; return; } int mid=(l+r)>>1; if(pos<=mid) update(l,mid,dex<<1,pos,flag,val); else update(mid+1,r,dex<<1|1,pos,flag,val); push_up(dex);}int main(){ int tot,pos,flag; while(~scanf("%d",&n)) { tot=0; for(int i=1;i<=n;i++) { scanf("%s",op[i]); if(op[i][0]!='s') { scanf("%d",&b[i]); a[tot++]=b[i]; } } sort(a,a+tot); tot=unique(a,a+tot)-a; if(tot==0) memset(tree[1].sum,0,sizeof(tree[1].sum)); else buildtree(1,tot,1); for(int i=1;i<=n;i++) { pos=lower_bound(a,a+tot,b[i])-a; pos++; if(op[i][0]=='a') { flag=1; update(1,tot,1,pos,flag,b[i]); } else if(op[i][0]=='d') { flag=-1; update(1,tot,1,pos,flag,b[i]); } else printf("%I64d\n",tree[1].sum[3]); } } return 0;}

版权声明:本文博客原创文章,博客,未经同意,不得转载。

你可能感兴趣的文章
iOS strong weak unowned引用
查看>>
JS每日一题: Call,Apply,Bind的使用与区别,如何实现一个bind?
查看>>
数据结构_Swift实现栈,队列,链表
查看>>
RAC(ReactiveCocoa)使用方法(一)
查看>>
大数据开发工程师学习路线分享
查看>>
[译] JavaScript 如何工作:渲染引擎和性能优化技巧
查看>>
疯狂kotlin讲义连载之Kotlin的基础类型-- Boolean型
查看>>
Android 源码分析之旅3 3 Camera源码分析(插件级API入门Framework)
查看>>
聊聊毕业设计系列 --- 项目介绍
查看>>
【译】Java NIO 简明教程系列之 NIO 简介
查看>>
Flutter动画之Flare的制作与使用
查看>>
你以为我在玩游戏?其实我在学编程!
查看>>
HBase入门教程
查看>>
RecyclerView 源码深入解析——绘制流程、缓存机制、动画等
查看>>
上下文详解(持续更新)
查看>>
React 之 Redux
查看>>
服务不专成通病,互联网家装领域渗透率低要怪土巴兔?
查看>>
OpenGL的缓存
查看>>
组件化开发之fastlane自动化开发组件
查看>>
Java高级特性增强-多线程
查看>>