三分一下第一座桥,三分一下第二座桥,貌似就解决了。
UOJ跑的死慢,bz也T掉了。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<iostream>
#define maxn 100010
#define inf 1000000000000000
using namespace std;
struct yts
{
int op1,x1,op2,x2;
}a[maxn];
int n,m,k,mx;
long long ans;
char s[10];
long long calc(int x,int y)
{
long long ans=0;
for (int i=1;i<=n;i++)
if (a[i].op1==a[i].op2) ans+=abs(a[i].x2-a[i].x1);
else ans+=min(abs(a[i].x2-x)+abs(a[i].x1-x),abs(a[i].x2-y)+abs(a[i].x1-y))+1;
return ans;
}
long long solve(int x)
{
long long ans=0;
if (k==1)
{
for (int i=1;i<=n;i++)
if (a[i].op1==a[i].op2) ans+=abs(a[i].x2-a[i].x1);
else ans+=abs(a[i].x2-x)+abs(a[i].x1-x)+1;
}
else
{
int l=0,r=mx;
while (r-l>=3)
{
int mid=l+(r-l)/3,midmid=r-(r-l)/3;
if (calc(x,mid)<=calc(x,midmid)) r=midmid; else l=mid;
}
ans=inf;
for (int i=l;i<=r;i++) ans=min(ans,calc(x,i));
}
return ans;
}
int main()
{
scanf("%d%d",&k,&n);
for (int i=1;i<=n;i++)
{
scanf("%s%d",s,&a[i].x1);
if (s[0]=='A') a[i].op1=0; else a[i].op1=1;
scanf("%s%d",s,&a[i].x2);
if (s[0]=='A') a[i].op2=0; else a[i].op2=1;
mx=max(mx,max(a[i].x1,a[i].x2));
}
int l=0,r=mx;
while (r-l>=3)
{
int mid=l+(r-l)/3,midmid=r-(r-l)/3;
if (solve(mid)<=solve(midmid)) r=midmid; else l=mid;
}
ans=inf;
for (int i=l;i<=r;i++) ans=min(ans,solve(i));
printf("%lld\n",ans);
return 0;
}