当前位置:编程学习 > C/C++ >>

hdu 4288 Coder (线段树)

题目大意:
三个操作,
add 在集合中插入一个数
del  在集合中删除一个数
sum 求出在这个集合中下标模 5 得 3的数的和
都保证序列有序
 
思路:
先把所有的数字输入进来    然后离散化    那么我们可以得到一个数组  就是在操作中会出现的要你插入的数
然后我们就可以开始update     我们把他们分别插入离散化之后的所对应的位置
然后线段树就维护这个区间   对5取模 为 0 1 2 3 4 的位置的所有的和   只是仅对于这个区间哦。并不是说他的下标
比如说  当S==E的时候   这个区间只有一个数  那么这个位置下标模5 就是1 
再者说  e-s+1 == 2 的时候  这个区间有两个数  那么第一个数就是mod 5==1 的  第二个就是==2的。。
然后cnt维护的是这个区间有多少个。
 
 
 
#include <iostream>  
#include <cstdio>  
#include <algorithm>  
#define lson num<<1,s,mid  
#define rson num<<1|1,mid+1,e  
#define maxn 100005  
  
typedef long long LL;  
using namespace std;  
  
LL tre[maxn<<2][5];  
LL cnt[maxn<<2];  
struct node  
{  
    char op[10];  
    LL w;  
}P[maxn];  
LL X[maxn];  
  
void build(int num,int s,int e)  
{  
    int mid=(s+e)>>1;  
    cnt[num]=0;  
    memset(tre[num],0,sizeof(tre[num]));  
    if(s==e)  
    {  
        return;  
    }  
    build(lson);  
    build(rson);  
}  
  
void pushup(int num)  
{  
    for(int i=0;i<5;i++)  
    tre[num][i]=tre[num<<1][i]+tre[num<<1|1][((i-cnt[num<<1])%5+5)%5];//这个地方有点难得想- =  
}  
  
void update(int num,int s,int e,int pos,int val,int k)  
{  
    cnt[num] += 2*k-1;  
    if(s==e)  
    {  
        if(k==1)tre[num][1]=val;  
        else tre[num][1]=0;  
        return;  
    }  
    int mid=(s+e)>>1;  
    if(pos<=mid)update(lson,pos,val,k);  
    else update(rson,pos,val,k);  
    pushup(num);  
}  
  
int main()  
{  
    int n;  
    while(scanf("%d",&n)!=EOF)  
    {  
        int tot=1;  
        for(int i=1;i<=n;i++)  
        {  
            scanf("%s",&P[i].op);  
            if(P[i].op[0]!='s')  
            {  
                scanf("%I64d",&P[i].w);  
                X[tot++]=(LL)P[i].w;  
            }  
        }  
        sort(X+1,X+tot);  
        tot=unique(X+1,X+tot)-(X+1);  
  
        build(1,1,tot);  
        for(int i=1;i<=n;i++)  
        {  
            if(P[i].op[0]!='s')  
            {  
                int pos = lower_bound(X+1,X+tot+1,P[i].w)-X;  
                if(P[i].op[0]=='a')update(1,1,tot,pos,P[i].w,1);  
                else update(1,1,tot,pos,P[i].w,0);  
            }  
            else printf("%I64d\n",tre[1][3]);  
        }  
    }  
    return 0;  
}  

 


补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,