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;
}
那么这一段的值一定是左边节点排序后余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;
}
相关文章推荐
- hdu 4288 Coder(树形结构-线段树)
- HDU 4288 Coder(12年成都网络赛-A题-离线 + 线段树)
- HDU 4288 Coder(线段树)
- HDU 4288 Coder [线段树]
- hdu 4267 分组线段树
- hdu 4288 线段树维护(增删有序数)
- HDU 4288线段树
- hdu 4288 线段树
- HDU 4288 Coder(线段树或者暴力vector)#by zh
- HDU-4288 Coder 线段树
- HDU 4288 Coder (线段树)
- HDU 4288 Coder 线段树维护区间%5的和
- hdu 4288 Coder(线段树)
- HDU 4288 Coder 线段树
- Coder- HDU 4288 线段树
- HDU 4288 线段树 + 离线处理
- HDU 4288 Coder(12年成都 线段树)
- HDU 4288 Coder(线段树)
- hdu 4288(线段树) Coder
- hdu 4288 Coder 线段树 区间合并