題目:
分析:每次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...