题目描述
太长了不写
题解
刚了几天刚出了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;
}
}