hdu 4288 线段树+离线+离散化

来源:互联网 发布:linux常用命令创建文件 编辑:程序博客网 时间:2024/04/29 07:34

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+1const 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;}


1 0
原创粉丝点击