日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

2017西安交大ACM小学期数据结构 [树状数组 离散化]

發(fā)布時間:2023/12/3 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2017西安交大ACM小学期数据结构 [树状数组 离散化] 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Problem E

發(fā)布時間: 2017年6月28日 12:53?? 最后更新: 2017年6月29日 21:35?? 時間限制: 1000ms?? 內(nèi)存限制: 64M

描述

給定一個長度為n的序列a1,?a2, ...,?an

給定兩個整數(shù)L,?R

輸出有多少個二元組(x,y),xy, 滿足Lyi=xaiR

9×104n105,??109ai109,??109LR109

輸入

第一行三個整數(shù)n,?L,?R, 意義如上所述。
第二行n個整數(shù), 表示序列a

輸出

一個數(shù), 表示答案。

樣例輸入1?復制 8 -6 6 3 -1 4 -1 5 -9 2 -6 樣例輸出1 28 題解:

要求區(qū)間和處于區(qū)間[L,R]之間的不同的區(qū)間有多少個。

看到要求區(qū)間和的問題,立刻想到樹狀數(shù)組。

但是現(xiàn)在有兩個比較棘手的問題需要處理

(1)負數(shù)下標問題(樹狀數(shù)組的下標不能為負數(shù),但是我們處理區(qū)間和的時候有可能產(chǎn)生負數(shù))

(2)區(qū)間和范圍太大,直接開辟如此大的樹狀數(shù)組肯定會MLE

因此,我們考慮這樣的方法,那就是離散化!


我們解決這道題目的總體上的思路就是

for循環(huán)sum[1...i]

然后判斷有多少個sum[1...j] (j <= i)使得sum[1....i] - sum[1...j] 在區(qū)間[L,R]內(nèi)

等價于L<=sum[i]-sum[j]<=R 等價于 sum[i]-R<=sum[j]<=sum[i]-L

這樣的話,我們把sum[i] (1<=i<=n)進行離散化(最多1e5個值)

我們用二分搜索找出sum[i]-R和sum[i]-L在離散化后的數(shù)列中的位置,也就是在樹狀數(shù)組中的位置。

然后直接求一個區(qū)間和就好了。

注意別忘了for循環(huán)體在一開始把sum[i-1]對應的離散值加入到樹狀數(shù)組里面去

代碼:

#include <cstdio> #include <iostream> #include <algorithm> using namespace std; typedef long long LL; const LL MAX = 1e5 + 7; const int N = 1e7 + 7; LL a[MAX],b[N]; int n; LL sm[MAX]; LL dis[MAX]; int mp[MAX]; LL L,R; inline LL lowbit(int x){return x & (-x); } LL getsum(int pos){LL res = 0;while(pos){res += b[pos];pos -= lowbit(pos);}return res; } void add(int pos,LL val){while(pos <= N){b[pos] += val;pos += lowbit(pos);} } int main(){scanf("%d%lld%lld",&n,&L,&R);for(int i = 1;i <= n;i++){scanf("%lld",&a[i]);//a[i] += stdi;dis[i-1] = sm[i] = sm[i-1] + a[i];}sort(dis,dis+n);int k = unique(dis,dis+n) - dis ;//cout<<k<<endl;for(int i = 1;i <= n;i++)mp[i] = lower_bound(dis,dis+n,sm[i]) - dis + 1;LL ans = 0;if(a[1] >= L && a[1] <= R) ans++;for(int i = 2;i <= n;i++){if(sm[i] >= L && sm[i] <= R) ans++;add(mp[i-1],1);LL x = sm[i] - R ;LL y = sm[i] - L;int idx = lower_bound(dis,dis+n,x) - dis ;int idy = lower_bound(dis,dis+n,y) - dis ;if(dis[idy] == y) idy ++;ans += getsum(idy) - getsum(idx);//printf("%d\n",getsum(idy) - getsum(idx));}printf("%lld\n",ans);return 0; } /* 3 0 0 0 0 0 3 -5 53 -1 4 */

總結

以上是生活随笔為你收集整理的2017西安交大ACM小学期数据结构 [树状数组 离散化]的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。