loj#2985. 「WC2019」I 君的商店
阿新 • • 發佈:2020-08-11
題目描述
太長了不寫
題解
剛了幾天剛出了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; } }