https://codeforces.com/gym/102155/problem/I
我们令S=_\sum{3^k},然后找中位数
可知左边右边就是S/2
然后我们让某一边全都少了一层,就相当于/3
那么减去的部分就是S/2*(2/3)=S/3,每次操作S就会变成2/3S
n=1e4,k=10的时候,50次刚好能让S<1,其实只要<=n就行了,因为3^0=1
选4也可
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxl=1e5+10;
int n,k,x,tot;
int res[maxl],up[maxl],mi[maxl];
ll pre[maxl];
struct node
{
int i,val;
}a[maxl];
inline bool cmp(const node &a,const node &b)
{
return a.i<b.i;
}
inline void gao()
{
int l=0;ll sum=0;
for(int i=1;i<=n;i++)
if(res[i]>0)
a[++l]=node{up[i],mi[res[i]]},sum+=mi[res[i]];
sort(a+1,a+1+l,cmp);
x=1;
for(int i=1;i<=l;i++)
pre[i]=pre[i-1]+a[i].val;
for(int i=1;i<=l;i++)
if(min(pre[i],sum-pre[i-1])>min(pre[x],sum-pre[x-1]))
x=i;
x=a[x].i;
cout<<x<<endl;
}
int main()
{
mi[0]=1;
for(int i=1;i<=10;i++)
mi[i]=mi[i-1]*3;
cin>>n>>k;
for(int i=1;i<=n;i++)
cin>>up[i],res[i]=k;
tot=0;
string s;
while(1)
{
++tot;
assert(tot<=50);
gao();
cin>>s;
if(s[0]=='E')
return 0;
if(s[0]=='<')
{
for(int i=1;i<=n;i++)
if(up[i]<=x && res[i]>0)
res[i]--;
}
else
{
for(int i=1;i<=n;i++)
if(up[i]>=x && res[i]>0)
res[i]--;
}
for(int i=1;i<=n;i++)
cin>>up[i];
}
return 0;
}