题解:P17278 『__OI R1』Hikari
lailai0916 · · 题解
题意简述
序列满足
解题思路
把序列再向后扩展一个辅助点。对
也就是说,
限制
第一个点固定绝对值,第二个点固定离开该点时的方向。因此,这两个高度条件也足以推出
两个已知点
必要性来自每步只能变化
把初始条件转换为
可行性解决后,再化简目标。原条件两边平方可得:
对
所以目标只与格路终点高度
设最后一个固定点为
平方函数在非负数上递增。离
每组数据的时间复杂度为
参考代码
#include <bits/stdc++.h>
using namespace std;
using ll=long long;
bool reach(pair<ll,ll> a,pair<ll,ll> b)
{
ll d=b.first-a.first;
ll h=abs(b.second-a.second);
return h<=d&&(d-h)%2==0;
}
ll root(ll x)
{
ll s=static_cast<ll>(sqrtl(static_cast<long double>(x)));
while((s+1)*(s+1)<=x)s++;
while(s*s>x)s--;
return s;
}
ll cost(ll x,ll n)
{
return abs(x*x-n-1);
}
void solve()
{
ll n;
int m;
cin>>n>>m;
vector<pair<ll,ll>> a={{0,0},{1,1}};
for(int i=0;i<m;i++)
{
ll w,c;
cin>>w>>c;
a.push_back({w,abs(c)});
a.push_back({w+1,abs(c+1)});
}
sort(a.begin(),a.end());
bool ok=1;
ll w=a[0].first,v=a[0].second;
int tot=a.size();
for(int i=1;i<tot;i++)
{
ll x=a[i].first,y=a[i].second;
if(x==w)
{
if(y!=v)ok=0;
continue;
}
if(!reach({w,v},a[i]))ok=0;
w=x;
v=y;
}
if(!ok)
{
cout<<-1<<'\n';
return;
}
ll d=n+1-w,l=max(0LL,v-d),r=v+d;
if(l%2!=(v+d)%2)l++;
ll s=root(n+1);
ll y=s;
if(y%2!=l%2)y--;
ll ans=min(cost(l,n),cost(r,n));
if(l<=y&&y<=r)ans=min(ans,cost(y,n));
y+=2;
if(l<=y&&y<=r)ans=min(ans,cost(y,n));
cout<<ans/2<<'\n';
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin>>t;
while(t--)solve();
return 0;
}