離散化 線段樹

2021-09-12 20:26:04 字數 1353 閱讀 8429

題目:

分析:每次1操作會往序列底加first個second,first 和 second 都是最大1e9的資料,每次2操作詢問序列中第first到第second個數的和

一開始就感覺有點像線段樹,輸入資料太大我們可以離線處理把資料離散化下,然後扔到線段樹上,維護兩個陣列:

sum: 區間數的值的和  num: 區間數的數量和  ,對於每次詢問的first和second,我們找到第first個和第second個分別是哪兩個數字,

如果兩個數字不相同,那麼就先算出分別取了多少個這兩個數字,對於兩個數字中間的數字和我們可以直接用線段樹區間求和得到

ac code:

#includeusing namespace std;

typedef long long ll;

const int maxn=100001;

const ll mod=1e9+7;

struct node;

node a[maxn];

int op[maxn];

ll b[maxn],sum[maxn<<2],num[maxn<<2],vis[maxn];

void update(ll pos,ll val,ll l,ll r,ll rt)

ll mid=(l+r)>>1;

if(pos<=mid) update(pos,val,l,mid,rt<<1);

else update(pos,val,mid+1,r,rt<<1|1);

sum[rt]=(sum[rt<<1]+sum[rt<<1|1])%mod;

num[rt]=num[rt<<1]+num[rt<<1|1];

}ll query(ll l,ll r,ll l,ll r,ll rt)///區間查詢[l,r]的數的值的和

ll mid=(l+r)>>1;

ll ans=0;

if(l<=mid) ans=(ans+query(l,r,l,mid,rt<<1))%mod;

if(mid=pos&&num[rt]-vis[r]>1;

if(pos<=num[rt<<1]) query1(pos,l,mid,rt<<1);

else query1(pos-num[rt<<1],mid+1,r,rt<<1|1);

}ll query2(ll l,ll r,ll l,ll r,ll rt)///求區間[l,r]有多少個數字

int main()

sort(b+1,b+1+k);///離散化處理

for(int i=1;i<=n;i++)

else

printf("%lld\n",ans);}}

return 0;

}

資料離散化 線段樹

前言 遇到了乙個矩形面積堆疊的問題,想了很久。終於找到了方法。先做個小記,待到具體問題時再分析。資料離散化 高大上的名字,其實就是對資料的一種處理,也可以採取陣列 或者 容器 map vector。之類的來儲存。之前的ibm技術俱樂部主席競選 那道題其實就是很好的應用。有些資料本身很大,自身無法作為...

紙帶 線段樹 離散化

題目大意 每次給一段區間染色,求最後整個區間有多少種顏色 分析 用膝蓋想也知道這題線段樹可以輕鬆水過,於是出題人靈機一動,挖了個深坑,每次給的區間是左開右閉的,但題目沒說,他給了你一張圖,你們可以感受一下 於是正解wa成0分我也是很絕望的。有一點要注意一下,離散化後有些區間會並在一起,原來中間的顏色...

線段樹 離散化 染色

這個題目太坑了,一直給報超時,然後調了一下午發現多開了乙個map。ac include include include include include include include includeusing namespace std define maxn 10000000 100 define...