題目描述
太長了不寫
題解
剛了幾天剛出了69分加一些奇奇怪怪的做法
subtask3
首先根據0和N-1可以找到1連續段的開頭,然後二分
把不確定性消掉,只需要兩個一組詢問即可,根據奇偶性討論之後的和只有0和2
subtask5
首先用2N的次數找到最大值,最大值一定是1
然後對於任意兩個數xy,先用2次來保證x>=y,然後3次詢問x+y與1的大小關係
如果x+y>=1則x=1,否則y=0,最後剩下的一個數根據奇偶性求出來
總次數是7N
瞎搞
沒有寫並不知道結果怎樣
在求最大值的時候啓發式合併,合出來的東西是一棵深度log有N/2個葉子的樹
從上往下按照樹邊詢問,因爲大小關係已經確定所以只需要3次
如果當前節點已經可以確定爲1就往子樹裏搞,因爲再搞下去可能得不到新的信息(如果某個點確定爲0那麼子樹都是0),最後剩下的再用subtask5的做法5*個數來搞
最壞情況下剩下的都是葉子,也就是說每個非葉子節點都詢問了一次,那麼次數是2N+3*N/2+5*N/2=6N
從葉子開始考慮可以更優,因爲一旦一個點是1那麼到根的路徑都是1
次數不知道是多少但是感覺查找的部分可以變成3*N/4,也就是總次數是21/4*N
subtask6
subtask5的瓶頸在於用2N次來確定1,因爲M=5N+100,所以考慮不確定具體的1而是得到一個單調的序列,最後用二分解決
維護一個數a和剩餘數序列,每次提出兩個數xy來考慮
首先用2次保證x>=y,然後詢問x+y與a的關係
如果a>=x+y那麼y=0把x丟回去,否則有x>=a,把a變成x把y丟回去
把所有的a按順序記下來,得到一個單調不減的序列和剩下的一個不確定數,用二分把數插進序列
由於max(ai,z)=1,所以得到1之後同subtask3二分確定序列
次數是5N+5log,如果不把數插進去直接二分可以做到3log但是不好寫所以沒寫
code
#include <bits/stdc++.h>
#include "shop.h"
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define ll long long
using namespace std;
void swap(int &x,int &y) {int z=x;x=y;y=z;}
void find_price(int task_id, int N, int K, int ans[]) {
int a[100001],b[100001],c[100001],d[100001],i,j,k,l,r,mid,t1=0,t2=0,x,y,z,sum,A,t;
bool bz;
if (task_id==3)
{
fo(i,1,N) a[i-1]=i-1,b[N-i]=i-1;
a[0]=0;b[0]=N-1;
bz=query(a,1,b,1);
l=1;r=(N-!K)/2-1;
while (l<r)
{
mid=(l+r)/2;
a[0]=0,b[0]=mid*2-1+(!K),b[1]=mid*2+(!K);
if (bz)
a[0]=(N-1)-a[0],b[0]=(N-1)-b[0],b[1]=(N-1)-b[1];
if (query(a,1,b,2))
l=mid+1; else r=mid;
}
a[0]=0,b[0]=l*2-1+(!K),b[1]=l*2+(!K);
if (bz)
a[0]=(N-1)-a[0],b[0]=(N-1)-b[0],b[1]=(N-1)-b[1];
l-=!query(a,1,b,2);
ans[0]=1;if (!K) ans[1]=1;
fo(i,1,l) ans[i*2-1+(!K)]=ans[i*2+(!K)]=1;
if (bz)
{
fo(i,1,N/2)
swap(ans[i-1],ans[(N-i+1)-1]);
}
}
else
{
l=N-1;
fo(i,1,N-1) c[i]=i;A=0;t=1;d[t]=0;
while (l>1)
{
x=c[l-1],y=c[l],l-=2;
a[0]=x,b[0]=y;
if (query(a,1,b,1)) swap(x,y);
a[0]=A,b[0]=x,b[1]=y;
if (!query(a,1,b,2))
ans[y]=0,c[++l]=x;
else
A=x,c[++l]=y,d[++t]=x;
}
a[0]=c[1],b[0]=d[t];
if (!query(a,1,b,1)) l=t+1;
else
{
l=1;r=t;
while (l<r)
{
mid=(l+r)/2;
a[0]=c[1],b[0]=d[mid];
if (!query(a,1,b,1))
l=mid+1; else r=mid;
}
}
fd(i,t+1,l+1) d[i]=d[i-1];d[l]=c[1];++t;
fd(i,t/2,1) swap(d[i],d[t-i+1]);
l=1;r=(t-1-!(K&1))/2;
while (l<r)
{
mid=(l+r)/2;
a[0]=d[1],b[0]=d[mid*2+!(K&1)],b[1]=d[mid*2+1+!(K&1)];
if (query(a,1,b,2))
l=mid+1; else r=mid;
}
if (l>r) --l;
else
{
a[0]=d[1],b[0]=d[l*2+!(K&1)],b[1]=d[l*2+1+!(K&1)];
l-=!query(a,1,b,2);
}
fo(i,1,l*2+1+!(K&1)) ans[d[i]]=1;
}
}