給你乙個長度為
n 的序列a[
],序列裡只包含數字1或2,
q 次詢問乙個數字
x,問序列裡是否存在乙個連續的區間[l
,r] ,使得∑r
i=la
[i]=
x ,並輸出乙個可行的區間。n,
q≤106
網上題解比較少,做法都是一樣的:即大小為
x 的區間可行時,x−
2大小的區間也是可行的,因此可以離線回答所有詢問,分奇數和偶數的
x 分開討論,先找出最大的奇數和偶數的
x以及乙個可行區間,然後倒著推x−
2,x−
4...
的可行區間
這裡我提出一種新的做法(感謝溫州中學au大爺林一諾提供的思路)。
我們對序列裡包含的1的個數不超過1和大於1分開討論:
1、1的個數小於等於1
在這個情況下,我們用特判來回答每個詢問,總的複雜度o(2、1的個數大於1q)如果1的個數為0,那麼詢問的
x 必須≤∑
a[i]
,且2|x
如果1的個數為1,若
xmod2=
∑a[i
]mod
2 ,則詢問的
x 必須≤∑
a[i]
;否則說明詢問的
x 是個偶數,必須只由2組成,看1左邊的2之和和1右邊的2之和分別是否大於等於
x(保證
x 能由1左邊的2或者1右邊的2裡找出乙個子區間湊出)
我們找出這個序列裡離左端點最近的1的位置lone和離右端點最近的1的位置n−
rone
+1序列一定是這個樣子:
22…221??…??122…22若x
>∑a
[i]−
2(min−1)
,則表明選擇的區間必須不得不選擇lo
ne和n−
rone
+1兩邊的2,若
xmod2=
∑a[i
]mod
2 ,且x≤
sum ,則顯然找得到可行區間
其他情況下,我們可以考慮在[l
one+
1,n]
區間進行二分,以及在[1
,n−r
one]
區間進行二分找出乙個位置
t ,使得x−
1≤∑t
i=lo
ne+1
≤x,或者x−1
≤∑n−
rone
i=t≤
x ,則找得到可行區間
顯然這樣的二分做法是正確的,因為只要存在合法區間,就肯定可以通過二分,在最左邊或最右邊的1旁邊找出連續的一段和,恰好等於
x 或x−
1,如果是x−
1 的話,就把那個1補上去就成了
x (序列裡只包含1或者2,因此只要存在合法區間,二分後就得不到乙個x−
3,x−
4...
大小的區間)
ps:若∑t
i=lo
ne+1
=x,或者∑n
−ron
ei=t
=x,則答案區間就是[l
one+
1,t]
([t,n−r
one]
);若∑t
i=lo
ne+1
=x−1
,或者∑n
−ron
ei=t
=x−1
,則答案區間就是[l
one,
t]([t
,n−r
one+1])
#include
#include
#include
#include
#include
#define maxn 2100000
using namespace std;
int n,m,a[maxn],cnt[3],sum=0; //cnt[1]=1的個數,cnt[2]=2的個數
char s[maxn];
namespace specialcheck //只有乙個1,特判
for(int i=1;i<=m;i++)
if((sum%2)==0&&(x
%2)!=(sum%2))
if((sum%2)==1&&(x
%2)==0)
}if((sum%2)==0)
//sum%2==1
if(x
%2==0)
printf("%d
%d\n",n-x/2+1,n);
}else}}
}namespace binarysearchedition //二分版
for(int i=n;i>=1;i--)
if(a[i]==1)
for(int i=1;i<=n;i++) presum[i]=presum[i-1]+a[i];
for(int t=1;t<=m;t++)
if(x>sum-2
*(min(lone,rone)-1))
continue;
}int lowerbound=lone+1,upperbound=n,ans=-1;
while(lowerbound<=upperbound)
else upperbound=mid-1;
}if(ans!=-1)
else
if(presum[ans]-presum[lone]==x-1)
}lowerbound=1,upperbound=n-rone,ans=-1;
while(lowerbound<=upperbound)
else lowerbound=mid+1;
}if(ans!=-1)
else
if(presum[n-rone]-presum[ans-1]==x-1) //!!!!!
}printf("nie\n");}}
}int main()
else
return
0;}
POI 2012 Well 二分 單調性
給你乙個長度為 n 的序列 a,每次操作可以讓其中乙個數字減1,最多能進行 m 次操作,問要使得存在某個ai 0的話,max 的最小值是多少 我們可以二分答案,此問題變為判定性問題 問要使得存在某個ai 0的話,max 是否可以小於等於mi d 我們首先要操作幾次,讓整個序列滿足 max 小於等於m...
NOIP2011 選擇客棧 二分,STL
有 n 間客棧,每間客棧按某種色調裝飾,總共 k 種,每家有最低消費 w i 兩個人打算選擇同種色調的兩家不同客棧入住,同時在他們之間要有一間客棧的 w i le p 求選擇的方案數。先將所有滿足 w i le p 的 i 標記為可用的,其它的標記為不可用的。考慮對於每乙個左端點,向右找到第乙個可用...
二分答案 NOIP 2011 聰明的質監員
題意 n n 個礦石,每個礦石都有自己的重量 wi role presentation style position relative wiw i,以及價值vi v i。接下來會進行以下四個操作 1.給定 m m 個區間 l i,ri role presentation style position...