主席樹 FJOI2016 神秘數

2021-10-25 02:18:21 字數 1538 閱讀 5651

展開

題目描述

乙個可重複數字集合s的神秘數定義為最小的不能被s的子集的和表示的正整數。例如s=,

1 = 1

2 = 1+1

3 = 1+1+1

4 = 4

5 = 4+1

6 = 4+1+1

7 = 4+1+1+1

8無法表示為集合s的子集的和,故集合s的神秘數為8。

現給定n個正整數a[1]…a[n],m個詢問,每次詢問給定乙個區間l,r,求由a[l],a[l+1],…,a[r]所構成的可重複數字集合的神秘數。

輸入格式

第一行乙個整數n,表示數字個數。

第二行n個整數,從1編號。

第三行乙個整數m,表示詢問個數。

以下m行,每行一對整數l,r,表示乙個詢問。

輸出格式

對於每個詢問,輸出一行對應的答案。

輸入輸出樣例

輸入 #1複製

51 2 4 9 10

51 1

1 21 3

1 41 5

輸出 #1複製24

888說明/提示

對於100%的資料點,n,m <= 100000n,m<=100000,∑a[i] <= 10^9∑a[i]<=10

9首先我們挖一下這道題的性質

假設我們s集合中的樹能表示的值域是[1,x],考慮新加進來乙個數t

如果t<=x+1那麼值域變為表示[1,x+t],否則值域不變,這是很容易證明的

所以暴力就是從小到大加數求值域

考慮怎麼優化這個過程

設當前值域[1,x]

則ans=x+1

若小於等於ans的數的和res≥ans,則一定有未選的且小於等於ans的數,令ans=res+1即可。

反之說明答案就是ansans,直接breakbreak

因為ai比較大,用主席樹維護

#include

#define mid ((lb+rb)>>1)

#define ll long long

using

namespace std;

int cnt,root[

1000001

],n,m;

const

int inf=

1e9;

struct node

seg[

5000001];

void

update

(int

&rt,

int lb,

int rb,

int x)

intquery

(int i,

int j,

int lb,

int rb,

int l,

int r)

intmain()

scanf

("%d"

,&m)

;while

(m--

)printf

("%d\n"

,pos+1)

;}}

FJOI2016 神秘數 主席樹

明白之後 5min 就寫好了 自閉 這題的題意是問你 l,r 區間的數字不能構成的數字的最小值 首先考慮 如果 1,x 可以被表示 那麼加入乙個 a i 顯然 1,x a i 都可以被表示 有什麼好辦法呢 當然有 o q sum r l 1 霧 區間求和問題啥的考慮主席樹,首先我不會證明複雜度,是因...

P4587 FJOI2016 神秘數 主席樹

題意 給出1e5個數 查詢l,r區間內第乙個不能被表示的數 比如1,2,4可以用子集的和表示出 1,7 所以第乙個不能被表示的是8 題解 先考慮暴力的做法 把這個區間內的數字按從小到大排序後 從前往後掃 當前能表示出 1,x 假設第i個數字y 1 x 那麼就可以表示 1,x y 如果y x 1那麼第...

FJOI2016 建築師 斯特林數

問題描述 小 z 是乙個很有名的建築師,有一天他接到了乙個很奇怪的任務 在數軸上建 n 個建築,每個建築的高度是 1 到 n 之間的乙個整數。小 z 有很嚴重的強迫症,他不喜歡有兩個建築的高度相同。另外小 z 覺得如果從最左邊 所有建築都在右邊 看能看到 a個建築,從最右邊 所有建築都在左邊 看能看...