hdu4288(オフライン+ +離散セグメントツリー)

免責事項:この記事はブロガーオリジナル記事です、続くBY-SAのCC 4.0を著作権契約、複製、元のソースのリンクと、この文を添付してください。
このリンク: https://blog.csdn.net/qq_43475173/article/details/102719525

タイトル

データを、各データ・インデックス= 3%と5のクエリー数列値を追加および削除することができ、列の多数の小さなを維持

問題の解決策

常にそれが唯一のその種の良い見つけるのに長い時間のように、一種のではないと思った最初は、少し簡単なポイント
の個別操作は、STLのLOWER_BOUND二つの機能とユニークで簡単に比較的簡単に行うことができている
理由は、オフラインセグメントからですノード操作の削除や追加を完了することができませんでしツリーの限界、最初からツリーラインのサイズが固定されるので、そのオフラインの方法を使用して、我々はすべてのデータの総数でツリーラインを確立するために、データの量を知ることができるようになります、これは、私たちは、その後、0に減少し、リーフ・ノードの下にCNT-1で運転削除、ノードの子の数を記録するために、削除操作のCNTを使用するので、このことができ、ツリーラインを高めるために、変形「追加」操作を完了しますノードがまだそこに実際にあるが、値が0であるため、私たちのフォロー和の計算には影響しません、CNTとターゲットの列の下に多数の彼の影響力を排除するために、この変数
のセグメントツリーは、その後、何も難しくありません、シングルポイントの更新セグメントツリーです、左のサブツリー右部分木プラス指数に必要右側のサブツリーの削減という、例えば、右のために注意すべきです 合計欄のツリーの最初の位置は(1 +はsizeof(左部分木))である必要があり、この時間は、CNTの変数がで重要な役割を果たしています

コード

#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);
}

おすすめ

転載: blog.csdn.net/qq_43475173/article/details/102719525
おすすめ