[BZOJ 4071] [Apio2015] bzojapio2015

Source: Internet
Author: User

[BZOJ 4071] [Apio2015] bzojapio2015

4071: [apio2015] The Bridge next to BA's neighbor
Time limit: 2000 MS

Memory limit: 262144 KB

Description

The city of Palembang is separated by Musi River into two zones. Let's call them zone A and zone B.

Each zone consists of exactly 1,000,000,001 buildings along the respective side of the river, conveniently numbered 0 through 1,000,000,000. the distance between every pair of adjacent buildings is 1 unit of distance. the width of the river is 1 unit of distance as well. building I in zone A is located on exactly the opposite side of building I in zone B.

N citizens live and work in the city. citizen I's house is in zone Pi, building Si, while his office is in zone Qi, building Ti. if a citizen must cross the river to go from his house to his office, he must take a boat. this has been uncomfortable, so the government has decided to build at most K bridges over the river, so that the citizens can go to work by driving. each bridge must be built exactly between two opposite buildings in the two zones. the bridges must be strictly perpendicular to the river. the bridges must not overlap each other.

Let Di be the minimum distance citizen I has to drive to go from his house to his office, after the government has built at most K bridges. help the government build the bridges in such a way that the sum D1 + D2 +... + DN is minimized.

Input Format

The first line contains two integers K and N. Each of the next N lines contains four tokens Pi, Si, Qi, and Ti.

Output Format

A single line containing the minimum sum of the distances.

Sample Input 1

1 5
B 0 A 4
B 1 B 3
A 5 B 7
B 2 A 6
B 1 A 7
Sample Output 1

24
Sample Input 2

2 5
B 0 A 4
B 1 B 3
A 5 B 7
B 2 A 6
B 1 A 7
Sample Output 2

22
Explanation

This is the authentication for both sample inputs.

Here is one possible solution for sample input 1. The pink stripe segment denotes a bridge.

And this is a possible solution for sample input 2:

Subtasks

For each subtask,

Pi and Qi will be either a character 'a' or A character 'B '.
0 ≤ Si, Ti ≤ 1,000,000,000
More than one house or office (or combination of both) can be located in the same building.
Subtask 1 (8 points)

K = 1
1 ≤ N ≤1,000
Subtask 2 (14 points)

K = 1
1 ≤ N ≤100,000
Subtask 3 (9 points)

K = 2
1 ≤ N ≤100
Subtask 4 (32 points)

K = 2
1 ≤ N ≤1,000
Subtask 5 (37 points)

K = 2
1 ≤ N ≤100,000

The weighted line segment tree dynamically maintains the median.

(The same side of the house and organization should be considered in advance)
After listing the calculated formula, we can find that the optimal solution is the median of all offices and home locations.

For K = 1 And the median can be directly obtained.

For K = 2 Can be found: According to everyone's home and officeMidpointAfter sorting, there must be a split point so that the prefixes all go to the bridge on the left, and the suffixes all go to the bridge on the right (because the bridge close to the midpoint will not be worse ).

So we enumerate the Split points. After discretization, we can use the weight line segment tree to dynamically maintain the median of the two intervals to solve the problem.

#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <map>#include <vector>#define pb push_back#define M 300005#define LL long longusing namespace std;LL ans[M];int size,n,k,cnt;int ls[M],d[M];char s1[10],s2[10];struct data{    int x[3];}a[M];struct Segtree{    int size;    LL sum;}t[M<<2];int z[10];void lisan(){    sort(ls+1,ls+1+cnt);    size=unique(ls+1,ls+1+cnt)-ls-1;}int Hash(int x){    return lower_bound(ls+1,ls+1+size,x)-ls;}bool cmp(data a,data b){    return a.x[1]+a.x[2]<b.x[1]+b.x[2];}void Update(int x){    t[x].sum=t[x<<1].sum+t[x<<1|1].sum;    t[x].size=t[x<<1].size+t[x<<1|1].size;}void Build(int x,int l,int r){    if (l==r)    {        t[x].sum=t[x].size=0;        return;    }    int m=(l+r)>>1;    Build(x<<1,l,m);    Build(x<<1|1,m+1,r);    Update(x);}void Insert(int x,int l,int r,int k){    if (l==r)    {        t[x].sum+=d[l];        t[x].size++;        return;    }    int m=(l+r)>>1;    if (k<=m) Insert(x<<1,l,m,k);    else Insert(x<<1|1,m+1,r,k);    Update(x);}LL Getsum(int x,int l,int r,int cnt){    if (t[x].size<=cnt)        return t[x].sum;    if (l==r)        return 1LL*cnt*d[l];    int m=(l+r)>>1;    if (t[x<<1].size>=cnt) return Getsum(x<<1,l,m,cnt);    else return t[x<<1].sum+Getsum(x<<1|1,m+1,r,cnt-t[x<<1].size);}LL Query(LL k){    LL s=Getsum(1,1,size,k);    return t[1].sum-2LL*s;}int main(){    scanf("%d%d",&k,&n);    LL pre=0;    int tot=0;    cnt=0;    for (int i=1;i<=n;i++)    {        int x1,x2;        scanf("%s%d%s%d",s1,&x1,s2,&x2);        if (s1[0]==s2[0])        {            pre+=abs(x1-x2);            continue;        }        pre++;        a[++tot].x[1]=x1,a[tot].x[2]=x2;        ls[++cnt]=x1,ls[++cnt]=x2;    }    if (cnt)    {        lisan();        n=tot;        for (int i=1;i<=n;i++)            d[Hash(a[i].x[1])]=a[i].x[1],d[Hash(a[i].x[2])]=a[i].x[2];        Build(1,1,size);        sort(a+1,a+1+n,cmp);        for (int i=1;i<=n;i++)        {            Insert(1,1,size,Hash(a[i].x[1]));            Insert(1,1,size,Hash(a[i].x[2]));            ans[i]=Query(i);        }    }    if (k==1)        cout<<ans[n]+pre<<endl;    else    {        LL Ans=ans[n];        if (size)        {            Build(1,1,size);            for (int i=n;i>1;i--)            {                Insert(1,1,size,Hash(a[i].x[1]));                Insert(1,1,size,Hash(a[i].x[2]));                Ans=min(Ans,ans[i-1]+Query(n-i+1));            }        }        cout<<Ans+pre<<endl;    }    return 0;}

The key to this question lies in the fact that median is required and the nature of the question sorted by the midpoint.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.