http://acm.hdu.edu.cn/showproblem.php?pid=4288

開始的时候,果断TLE,做的方法是,线段树上只维护%5==3的坐标,比方1 2 3 4 5 6 7  假设删除第三个数,就将3,6的位置全+1,就是向右偏移以为,可是求和还是非常慢,所以即使10秒,还是TLE。。。

正确做法:

1、节点内维护sum[0...4]分别代表区间内%5==i的和

2、结点维护点的个数,cnt

3、离散化处理,然后每次插入时,经过的结点cnt+1或-1,叶子节点Sum[0]就是节点值,父节点的sum这样维护了:非常不错的方法

void pushup(int rt)
{
for(int i=0;i<5;i++)
nodes[rt].sum[i]=nodes[ls(rt)].sum[i]+nodes[rs(rt)].sum[ ((i-nodes[ls(rt)].cnt)%5+5)%5 ];
}

4、离散化+离线,能够使删除数比較方便,不用map

新学会的离散化方法:

for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
tmp[num++]=a[i];
}
sort(tmp,tmp+num);
num=unique(tmp,tmp+num)-tmp;
//然后能够这样查询位置
int pos=lower_bound(tmp,tmp+num,a[i])-tmp;

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <set>
#include <map>
using namespace std;
#define IN(s) freopen(s,"r",stdin)
#define CL(a,b) memset(a,b,sizeof(a))
#define ll long long
#define ls(rt) rt*2
#define rs(rt) rt*2+1
const int MAXN = 1e5+100; struct Node{
int l,r;
ll sum[5]; //
int cnt; //区间内数的个数
}nodes[MAXN*4]; int a[MAXN],n,tmp[MAXN];
char op[MAXN][6]; void build(int rt,int l,int r)
{
nodes[rt].l=l;
nodes[rt].r=r;
nodes[rt].cnt=0;
CL(nodes[rt].sum,0);
if(l==r)return;
int mid=(l+r)/2;
build(ls(rt),l,mid);
build(rs(rt),mid+1,r);
} void pushup(int rt)
{
for(int i=0;i<5;i++)
nodes[rt].sum[i]=nodes[ls(rt)].sum[i]+nodes[rs(rt)].sum[ ((i-nodes[ls(rt)].cnt)%5+5)%5 ];
} void update(int rt, int pos, int d, int flag)
{
nodes[rt].cnt+=flag;
if(nodes[rt].l == nodes[rt].r)
{
nodes[rt].sum[0]+=d;
return;
}
if(pos<=nodes[ls(rt)].r)update(ls(rt),pos,d,flag);
else update(rs(rt),pos,d,flag);
pushup(rt);
} int main()
{
//IN("hdu4288.txt");
int num;
while(~scanf("%d",&n))
{
num=0;
for(int i=0;i<n;i++)
{
scanf("%s",op[i]);
if(op[i][0]!='s')
{
scanf("%d",&a[i]);
tmp[num++]=a[i];
}
}
sort(tmp,tmp+num);
num=unique(tmp,tmp+num)-tmp;
build(1,1,num);
for(int i=0;i<n;i++)
{
int pos=lower_bound(tmp,tmp+num,a[i])-tmp;
if(op[i][0] == 'a')update(1,pos,a[i],1);
if(op[i][0] == 'd')update(1,pos,-a[i],-1);
if(op[i][0] == 's')printf("%I64d\n",nodes[1].sum[2]);
}
}
return 0;
}

hdu 4288 线段树+离线+离散化的更多相关文章

  1. 玲珑oj 1117 线段树+离线+离散化,laz大法

    1117 - RE:从零开始的异世界生活 Time Limit:1s Memory Limit:256MByte Submissions:438Solved:68 DESCRIPTION 486到了异 ...

  2. hdu 4288 线段树 暴力 **

    题意: 维护一个有序数列{An},有三种操作: 1.添加一个元素. 2.删除一个元素. 3.求数列中下标%5 = 3的值的和. 解题思路: 看的各种题解,今天终于弄懂了. 由于线段树中不支持添加.删除 ...

  3. hdu 4419 线段树 扫描线 离散化 矩形面积

    //离散化 + 扫描线 + 线段树 //这个线段树跟平常不太一样的地方在于记录了区间两个信息,len[i]表示颜色为i的被覆盖的长度为len[i], num[i]表示颜色i 『完全』覆盖了该区间几层. ...

  4. HDU 3607 线段树+DP+离散化

    题意:从左往右跳箱子,每个箱子有金币数量,只能从矮处向高处跳,求最大可获得金币数,数据规模1<=n<=1e5. 显然是一个dp的问题,不难得出dp[ i ] = max(dp[j] )+v ...

  5. J - Super Mario HDU - 4417 线段树 离线处理 区间排序

    J - Super Mario HDU - 4417 这个题目我开始直接暴力,然后就超时了,不知道该怎么做,直接看了题解,这个习惯其实不太好. 不过网上的思路真的很厉害,看完之后有点伤心,感觉自己应该 ...

  6. HDU 4288 线段树+离散化

    题意: n个操作 在[1, 100000]  的区间上add 或del数( 必不会重复添加或删除不存在的数) sum 求出整个集合中 (下标%5 == 3 位置) 的数   的和 注意数据类型要64位 ...

  7. 覆盖的面积 HDU - 1255 线段树+扫描线+离散化 求特定交叉面积

    #include<cstdio> #include<map> #include<algorithm> using namespace std; ; struct N ...

  8. HDU 1542 线段树+扫描线+离散化

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Su ...

  9. hdu 5877 线段树(2016 ACM/ICPC Asia Regional Dalian Online)

    Weak Pair Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total ...

随机推荐

  1. class的基本操作方法

    JavaScript语言中,生成实例对象的传统方法是通过构造函数 function Point(x,y){ this.x = x; this.y = y; } Point.prototype.toSt ...

  2. IOS系统兼容input keyup事件

    最近在做移动端模糊搜索功能,js监听input的keyup事件,在chrom模拟器和android手机环境运行都没有问题,到了ios手机却出现bug,没法实现功能: 查了好一会资料,发现keyup事件 ...

  3. LeetCode OJ 215. Kth Largest Element in an Array 堆排序求解

    题目链接:https://leetcode.com/problems/kth-largest-element-in-an-array/ 215. Kth Largest Element in an A ...

  4. 阅读《Android 从入门到精通》(10)——单项选择

    单项选择(RadioGroup) RadioGroup 是 LinearLayout 的子类,继承关系例如以下: android.view.ViewGroup android.widget.Linea ...

  5. nyoj--37--回文字符串(动态规划)

    回文字符串 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 所谓回文字符串,就是一个字符串,从左到右读和从右到左读是完全一样的,比如"aba".当然, ...

  6. 子文件夹的遍历(python、matlab)

    1. python 使用 os.listdir:Python Tricks(九)-- 递归遍历目录下所有文件 使用 os.walk: os.walk返回的是生成器(Generator),需迭代访问: ...

  7. 几个常用ORACLE运维监控的SQL语句

    1.消耗CPUSELECT a.CPU_TIME, --CPU时间 百万分之一(微秒)              a.OPTIMIZER_MODE,--优化方式              a.EXEC ...

  8. MongoDB 系列(一) C# 类似EF语法简单封装

    之前写过一篇关于MongoDB的封装 发现太过繁琐 于是打算从新写一篇简易版 1:关于MongoDB的安装请自行百度,进行权限认证的时候有一个小坑,3.0之后授权认证方式默认的SCRAM-SHA-1模 ...

  9. 将hexo的评论系统由gitment改为Valine

    title: 将hexo的评论系统由gitment改为Valine toc: false date: 2018-09-13 15:10:56 categories: methods tags: hex ...

  10. 初识Git(二)

    与我们前一篇随笔一样创建文件夹,init我们创建的文件夹,并且创建一个test.txt文本文件,add文本文件,commit文本文件,接下来在文本文件中添加文本: 与上一次不同的是我们这一次在编辑文件 ...