hdu 4288 Coder 成都賽區 線段樹

2022-03-15 12:15:19 字數 1690 閱讀 8580

題意:給出乙個有序集合,3種操作。插入乙個數,刪除乙個數,都保證序列有序。以及求和

其中求和是將下標%5==3的所有數求和;

題解: 線段樹   + 離散化 + 離線處理

一開始也是想的 線段樹 ,但是 這個和以前的 做過的 乙個線段樹 不同的 是 ,如果 我們 刪除 乙個 元素後  ,那麼 他的 下標 將會 改變 ,比賽是 不知  如何下手 。。。。。

同樣 是 用 5棵線段樹   維護 ,s[0]表示 %5  == 1 的 下標,其他 依次類推  cnt,記錄 子樹的 元素個數。

想要得到該區間內所有模5等3所有元素的和,左孩子可以求到,兩個孩子相互獨立,所以求右孩子需要知道(左子樹含有 )多少個元素,因為這樣分開求的時候,我們才知道 求右孩子時應該求下標模5等幾()的所有元素的和。

假如我們 求  i ==  3 時 (表示  %5 == 4),對於 左子樹 我們 直接 求 就可以 ,但是 對於 右子樹,我們 要知道 在 i== 3 的 情況下 ,右子樹的 元素的下標 應該 是 %5 == 幾?

p[x].s[i] = p[x*2].s[i] + p[x*2+1].s[((i  - p[x*2].cnt)%5 + 5)% 5];

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define min(a,b) a#define max(a,b) a>b?a:b

#define cl(a,num) memset(a,num,sizeof(a));

#define eps  1e-12

#define inf   10000000

//freopen("data.txt","r",stdin);

const

double pi  = acos(-1.0);

typedef   __int64  ll;

const

int maxn = 101000 ;

using

namespace std;

char c[6];

struct node

p[maxn*4] ;

ll  a[maxn],b[maxn],tp[maxn] ;

void build(int x,int l,int r)

void add(int x,int pos,int k)

int  mid = (p[x].l + p[x].r) >> 1;

if(pos <=mid )add(x*2,pos,k);

else add(x*2+1,pos,k);

for(int i = 0 ; i< 5;i++)

}int main()

if(c[0] == 'd')

if(c[0] == 's')

}sort(a,a+num) ;

int tot = unique(a,a+num) - a ;

build(1,0,tot - 1);

for(i = 0  ; i< n;i++)

if(tp[i] == 1)

if(tp[i] == 2)

printf("

%i64d\n

",p[1].s[2]);}}

hdu 4288 Coder(單點操作,查詢)

題意 三種操作 1.add x add the element x to the set 2.del x remove the element x from the set 3.sum find the digest sum of the set.the digest sum should be u...

無聊題目大紀實(HDU 4288 Coder)

這神題,暴力陣列可過,vector可過,線段樹可過。時限拉的太長了,所以就成水題了。不過比賽的時候真的沒敢用陣列暴力寫。說說線段樹的思路吧。對樹的每個節點 l,r,cnt,sum 5 分別表示左區間,右區間,這段區間上的點數,這段區間上sum x 5 的和。先把所有的資料都讀入,然後離散化,去掉重複...

hdu4288 Coder(線段樹單點更新)

題意 支援增刪,查操作,最後的序列式遞增的。做法 主要是如何維護mod5的sum值,這裡左兒子可以不用管,關鍵是右兒子的處理,可以假設右兒子有t個節點,左兒子有cnt個節點,則令 t cnt mod 5 i 則tmod5 i cnt mod 5 mod 5 所以剩下的就是維護每個節點的節點總數以及相...