列表

详情


NC17355. City

描述

    美团打车是美团的一项重要业务,在努力为用户提供便捷出行服务选择的同时,也希望能充分利用平台的力量,为司机带来更多的价值。
    众所周知,大城市上班族的出行会造成几个特定时间点的高峰期,比如早高峰和晚高峰。通常在两个高峰期之间,用户的出行需求会较少,司机会选择在一些合适的地点等待下一单生意。美团希望能够利用大数据的力量辅助司机决策,计算在哪个地点等待能够使得到用户上车地点的期望时间最短。
    经过抽象和简化,我们认为一块区域能够被描述成n行m列的马路,这些马路每行每列都会交叉。如果我们把它抽象成一个平面直角坐标系,东西方向的马路可以看做y=y1, y=y2, ..., y=yn这样的直线,南北方向的马路可以看做x=x1, x=x2, ..., x=xm这样的直线。
    经过美团大数据统计,用户可能的上车地点共有k个,第i个地点坐标为(ai, bi)。这些地点的位置都在路边上,也就是说它的横坐标会和某条南北向的马路的坐标相同或者说纵坐标会和某条东西向的马路坐标相同。当然也有可能两个都相同,也就是说这个地点的位置在某个路口。根据历史数据统计,每个上车地点有不同的权重ci,简单来说,就是下一单出现在第i个地点的概率为ci/(c1+c2+…+ck)。
    当一个用户订单出现的时候,司机会在马路上沿着最短路径尽快赶往上车地点。我们希望能找到一个合适的位置(必须在路边或路口),使得该位置到用户下一次上车地点的期望时间最短。
    同时我们还希望对每个司机,我们能快速地回答这个位置到下一次上车地点的期望时间,我们会给出q个询问。

输入描述

第一行三个整数n, m, k(1≤n, m, k≤100,000)。第二行包含n个整数y1, y2, ..., yn(0≤y1<y2<...<yn≤1,000,000)。第三行包含m个正整数x1, x2, ..., xn(0≤x1<x2<...<xm≤1,000,000)。接下来k行,每行包含3个整数ai, bi, ci (0≤ai,bi,ci≤1,000,000),保证ci之和大于0。
接下来一行一个整数q(0≤q≤100,000),接下来q每行两个整数ui,vi(0≤ui,vi≤1,000,000),表示一个司机所在的位置,保证司机和用户的位置都在路边或者路口。

输出描述

为了保证是整数,我们把期望的时间乘上ci的总和。
第一行输出最短的期望时间乘以ci之和。接下来q行,表示q个司机的位置所需要的期望时间乘上ci之和。

示例1

输入:

3 3 3
2 4 6
2 4 6
2 3 1
4 5 1
5 2 1
2
5 4
4 3

输出:

7
10
8

说明:

最合适位置是(4,4)这个点

示例2

输入:

3 3 3
2 4 6
2 4 6
2 3 1
4 5 100
5 2 1
0

输出:

8

说明:

最合适位置是(4,5)这个点

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 856ms, 内存消耗: 65176K, 提交时间: 2019-01-07 17:02:45

#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
const ll mod=1000000007;
ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
// head

const int N=101000;
const int inf=1000001;

int n,m,k,x[N],y[N],a[N],b[N],c[N],col[N],row[N],xa,ya,q;

struct linearwise {
 bool fg=0;
 vector<PII> p;
 vector<ll> sa,sc;
 ll z;
 void init() {
  fg=0; z=0;
  p.clear();
  sa.clear(); sc.clear();
 }
 void rebuild() {
  fg=1;
  sort(all(p));
  sa.clear(); sc.clear();
  ll pa=0,pc=0;
  rep(i,0,SZ(p)) {
   pc+=p[i].se;
   pa+=1ll*p[i].fi*p[i].se;
   sa.pb(pa); sc.pb(pc);
  }
 }
 ll query(int x) {
  if (p.empty()) return 0;
  if (!fg) rebuild();
  auto it=lower_bound(all(p),mp(x,-inf*2))-p.begin();
  ll pc=it?sc[it-1]:0,pa=it?sa[it-1]:0;
  return z+pc*x-pa+(sa.back()-pa-(sc.back()-pc)*x);
 }
 void add(ll aa,ll cc) {
  // c |x-a|
  fg=0;
  p.pb(mp(aa,cc));
 }
 void add(ll cc) {
  z+=cc;
 }
};

linearwise allr,allc,segc[N],segr[N];
map<int,linearwise> ssegc[N],ssegr[N];
ll gao(int *x,int *a,int *c,int n,int m) {
 int l=0,r=n-1;
 auto eval=[&](int k) {
  ll s=0;
  rep(i,0,m) s+=(ll)c[i]*abs(x[k]-a[i]);
  return s;
 };
 while (l+3<r) {
  int fl=(l+l+r)/3,fr=(l+r+r)/3;
  ll sl=eval(fl),sr=eval(fr);
  if (sl>sr) l=fl; else r=fr;
 }
 ll ans=1ll<<60;
 //cout << l << ' ' <<r <<endl;
 rep(i,l,r+1) ans=min(ans,eval(i));
 //cout << eval(0) << ' ' <<eval(1) << endl;
 return ans;
}

ll query(int a,int b) {
 int r=upper_bound(x,x+m+2,a)-x-1;
 int c=upper_bound(y,y+n+2,b)-y-1;
 //printf("%d %d %d %d %d %d\n",r,c,x[r],y[c],a,b);
 if (x[r]==a&&y[c]==b) {
  return allr.query(a)+allc.query(b);
 }
 if (x[r]==a) {
  ll ans=allr.query(a)+allc.query(b)+segc[c].query(b);
  if (ssegc[c].count(r)) ans+=ssegc[c][r].query(b);
  return ans;
 }
 if (y[c]==b) {
  ll ans=allr.query(a)+allc.query(b)+segr[r].query(a);
  if (ssegr[r].count(c)) ans+=ssegr[r][c].query(a);
  return ans;  
 }
 assert(0);
 return 0;
}
int main() {
 scanf("%d%d%d",&n,&m,&k);
 y[0]=-inf; y[n+1]=2*inf;
 x[0]=-inf; x[m+1]=2*inf;
 rep(i,1,n+1) scanf("%d",y+i);
 rep(i,1,m+1) scanf("%d",x+i);
 rep(i,0,k) scanf("%d%d%d",a+i,b+i,c+i);
 rep(i,0,k) {
  allr.add(a[i],c[i]);
  allc.add(b[i],c[i]);
 } 

 rep(i,0,k) {
  row[i]=upper_bound(x,x+m+2,a[i])-x-1;
  col[i]=upper_bound(y,y+n+2,b[i])-y-1;
  if (x[row[i]]==a[i]&&y[col[i]]==b[i]) {
   continue;
  }
  if (x[row[i]]==a[i]) {
   segc[col[i]].add(b[i],-c[i]);
   segc[col[i]].add(y[col[i]]+y[col[i]+1]-b[i],-c[i]);
   segc[col[i]].add((ll)c[i]*(y[col[i]+1]-y[col[i]]));
   ssegc[col[i]][row[i]].add(y[col[i]]+y[col[i]+1]-b[i],c[i]);
   ssegc[col[i]][row[i]].add(-(ll)c[i]*(y[col[i]+1]-y[col[i]]));
   ssegc[col[i]][row[i]].add(b[i],c[i]);
  }
  if (y[col[i]]==b[i]) {
   segr[row[i]].add(a[i],-c[i]);
   segr[row[i]].add(x[row[i]]+x[row[i]+1]-a[i],-c[i]);
   segr[row[i]].add((ll)c[i]*(x[row[i]+1]-x[row[i]]));
   ssegr[row[i]][col[i]].add(x[row[i]]+x[row[i]+1]-a[i],c[i]);
   ssegr[row[i]][col[i]].add(-(ll)c[i]*(x[row[i]+1]-x[row[i]]));
   ssegr[row[i]][col[i]].add(a[i],c[i]);
  }
 }

 ll r1=gao(x + 1,a,c,m,k)+gao(y + 1,b,c,n,k);

 fprintf(stderr,"%lld ",r1);
 rep(i,0,k) r1=min(r1,query(a[i],b[i]));
 fprintf(stderr,"%lld\n",r1);

 printf("%lld\n",r1);
 scanf("%d",&q);
 rep(i,0,q) {
  scanf("%d%d",&xa,&ya);
  printf("%lld\n",query(xa,ya));
 }
}

上一题