您的位置:首页 > 编程语言 > Go语言

hdu 4288 分组线段树

2014-06-24 06:35 225 查看
分组的形式还是余数 但是这次代表的是每个区间里排序的%5后的值

那么这一段的值一定是左边节点排序后余5得出的序号的值 然后加上右边的节点排序后的序号和左边的个数相加后

余5的值

比如左边的节点有7个数,右边的第6个数是这一段中的第几个数呢?

就是((7%5)+6)%5=3

所以就要把这第六个数的值加到第3棵树上的对应区间节点去 想通了以后就比较简单了

#include<iostream>
#include<stdio.h>
#include<cstdio>
#include<string.h>
#include<algorithm>
using namespace std;
#define ls (rt<<1)
#define rs (rt<<1|1)
#define mid ((l+r)>>1)
#define ll __int64
#define maxn 111111
ll sum[maxn<<2][5];
int num[maxn<<2];
void build(int rt,int l,int r){
for(int i=0;i<5;++i)sum[rt][i]=0;
num[rt]=0;
if(l==r)return ;
build(ls,l,mid);
build(rs,mid+1,r);
}
void up(int rt,int l,int r){
int lnum=num[ls];
for(int i=0;i<5;++i)sum[rt][i]=sum[ls][i];
for(int i=0;i<5;++i)sum[rt][(lnum+i)%5]+=sum[rs][i];
num[rt]=num[ls]+num[rs];
}
void ins(int rt,int l,int r,int L,int R,ll w){
if(L<=l&&r<=R){
num[rt]=1-num[rt];
sum[rt][1]=num[rt]?w:0;
return ;
}
if(L<=mid)ins(ls,l,mid,L,R,w);
if(mid<R)ins(rs,mid+1,r,L,R,w);
up(rt,l,r);
}
char op[maxn][15];
int cnt,n,m;
ll f;
char ss[100];
ll x[maxn],ox[maxn];
int bin(int r,ll va){
int l=0;
while(l<=r){
if(x[mid]==va)return mid;
else if(va>x[mid]){
l=mid+1;
}
else r=mid-1;
}
return -1;
}
int main()
{
while(~scanf("%d",&n)){
cnt=0;
for(int i=0;i<n;++i){

scanf("%s",op[i]);
if(op[i][0]=='a'||op[i][0]=='d'){
scanf("%I64d",&f);
ox[i]=x[cnt++]=f;
}
}

//离散化
sort(x,x+cnt);
int j=0;
for(int i=1;i<cnt;++i)if(x[i]!=x[j])x[++j]=x[i];
cnt=j+1;

build(1,1,cnt);

for(int i=0;i<n;++i){
// printf("\n%s",op[i]);
if(op[i][0]=='a'||op[i][0]=='d'){
// printf("ox:%lld\n",ox[i]);
int pos=bin(j,ox[i])+1;

// printf("%d ",pos);
ins(1,1,cnt,pos,pos,ox[i]);
}
else printf("%I64d\n",sum[1][3]);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  algorithm