hdu4288 (offline + + discrete segment tree)

Disclaimer: This article is a blogger original article, follow the CC 4.0 BY-SA copyright agreement, reproduced, please attach the original source link and this statement.
This link: https://blog.csdn.net/qq_43475173/article/details/102719525

topic

Maintain a small to large number of columns, can add and delete data, query number sequence value of each data index = 3% and 5

answer

At first, always thought it was not the sort of, like a long time only to find that sort good, a little simple point
discrete operation is relatively simple, can be done easily with the STL lower_bound two functions and unique
reason is because the offline segment limitations of the tree, unable to complete the deletion or addition of node operation, because the size of the tree line from the start is to be fixed, so use an offline way, we will be able to know the amount of data to establish tree line by the total number of all data, this completes the deformation "add" operation to increase the tree line, we can use a delete operation cnt to record the number of children of a node, delete operation is to the bottom of the leaf nodes is reduced to 0, then cnt-1, so this node is actually still there, but because the value is 0, does not affect our follow-sum calculations, with cnt this variable to eliminate his influence on the number under the columns of the target
segment tree, then nothing is difficult, is a single-point update segment tree , should be noted that the left subtree right subtree plus the need to index the right sub-tree reduction, for example, because the right Tree first position in total column should be (1 + sizeof (left subtree)), this time cnt variables play a crucial role in the

Code

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define maxn 100010
#define lson rt<<1
#define rson rt<<1|1
#define ll long long int
using namespace std;
int a[maxn],b[maxn],T;
char p[maxn],c[5];
struct Tre
{
	int l,r,cnt;
	ll sum[5];
}tre[maxn<<2];
void pushup(int rt)
{
	for(int i=0;i<5;i++)
	tre[rt].sum[i]=tre[lson].sum[i]+tre[rson].sum[((i-tre[lson].cnt)%5+5)%5];
}
void build(int rt,int l,int r)
{
	tre[rt].l=l;
	tre[rt].r=r;
	tre[rt].cnt=0;
	for(int i=0;i<5;i++) tre[rt].sum[i]=0;
	if(l==r) return;
	int mid=(l+r)>>1;
	build(lson,l,mid);
	build(rson,mid+1,r);
}
void update(int rt,int pos,int add)
{
	tre[rt].cnt+=add;
	if(tre[rt].l==tre[rt].r){
		tre[rt].sum[1]+=add*b[pos-1];
		return ;
	}
	int mid=(tre[rt].l+tre[rt].r)>>1;
	if(pos<=mid) update(lson,pos,add);
	else update(rson,pos,add);
	pushup(rt);
}
int main()
{
	//freopen("1.txt","r",stdin);
	int k,j;
	while(scanf("%d",&T)==1){
		k=0;j=0;
		int f;
		for(int i=1;i<=T;i++){
			scanf("%s",c);
			p[i]=c[0];
			if(p[i]!='s'){
				scanf("%d",&a[k++]);
				b[k-1]=a[k-1];
			}
		}
		sort(b,b+k);
		int n=unique(b,b+k)-b;
		build(1,1,n);
		for(int i=1;i<=T;i++){
			if(p[i]=='s'){
				printf("%I64d\n",tre[1].sum[3]);
				continue;
			}
			if(p[i]=='a') f=1;
			else f=-1;
			int pos=lower_bound(b,b+n,a[j++])-b+1;
			update(1,pos,f);
		}
	}
	//fclose(stdin);
}

Guess you like

Origin blog.csdn.net/qq_43475173/article/details/102719525