jzoj5432. A set of training to improve NOIP2017 [10.28] triples

Description

X + Y + Z has triples (x [i], y [ i], z [i]), the number you are picked from each triplet, and the following conditions are met:
1, each triplet group can be selected, and only a number (i.e., x [i], y [i ], z a [i] in)
2 to select the number of triples x [i] is exactly X-
. 3, select y [ i] is the number of triples exactly the Y
. 4, to select the number of triples Z [i] is exactly the number of Z and Q is the largest number selected
Q and the selected number is the largest number

Input

The first three lines represent non-negative integers X, Y, Z
next X + Y + Z three lines each describe a non-negative integer triples (x [i], y [ i], z [i] )

Output

Line and a selected integer number is the largest number

Sample Input

Input 1:
1 2 1
2. 4. 4
. 3 2 1
. 7. 6. 7
. 5 2. 3
input 2:
. 3 2. 3
16. 17 1
2. 7. 5
2 12 is 16
. 17. 7. 7
13 is 2 10
12 is 18 is. 3
16 15. 19
. 5. 6 2

Sample Output

Output 1:
18 is
output 2:
110

Data Constraint

For 10% of the data satisfies, 1 <= X + Y + Z <= 15
to 30% of the data satisfies, 1 <= X + Y + Z <= 100
for the other 10% of the data satisfies, X = 0
for the other 20 % of data satisfies all of the triad x [i] = 0
for the other 20% of data satisfies, 1 <= X + Y + Z <= 100000
to 100% of the data satisfies, 1 <= X + Y + Z <= 500000,0 <= x [ i], y [i], z [i] <= 500000

Competitions

30 minutes directly seconds.
10% thought suddenly thought a magic method, directly selected from all y, and then sort the yz, can be selected from a minimum z.
The perfect solution.
Then thought the remaining 20%, 10% as silly to think that the same can be greedy.
However, it seems hung up.
Still too dishes.

answer

The method of solution to a problem can not read?
It touches on the Internet has a magical stack approach.
The difference is the use of thinking.

First of all the yx, zx, triplet becomes so additional 20% of cases.
20 minutes to do this?
Since some groups can not, a little headache.
but! Some useful properties of the heap! !

First, according to the same yz sort.
Set \ (ansy _ {[i] } \) represents an i-th inside of the front, the selected maximum value of y-y.
Set \ (ansz _ {[i] } \) represents the i-th inside a selected maximum value of z z.
Both use the heap to maintain stuff, you can perfect solution -

Last answer + \ (\ the X-SUM \) to

Standard process

Faster than a lot of words did not bring with log run log, ever since the heap is the roar.

#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <cctype>
using namespace std;
const int maxn=500010;

struct node{
    long long x,y,z;
};

node a[maxn];
long long X,Y,Z,x[maxn],y[maxn],z[maxn],tot,d[maxn];
long long ansy[maxn],ansz[maxn],answer,sum;

__attribute__((optimize("-O3")))
inline int read()
{
    int X=0,w=0; char ch=0;
    while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
    while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    return w?-X:X;
}

__attribute__((optimize("-O3")))
void qsort(int l,int r)
{
    int i=l;int j=r;
    int m=a[(i+j)/2].x;
    while (i<=j)
    {
        while (a[i].x>m) i++;
        while (a[j].x<m) j--;
        if (i<=j)
        {
            swap(a[i],a[j]);
            i++;j--;
        }
    }
    if (l<j) qsort(l,j);
    if (r>i) qsort(i,r); 
}

__attribute__((optimize("-O3")))
void up(int x)
{
    while (x>1 && d[x/2]>d[x])
    {
        swap(d[x/2],d[x]);
        x/=2;
    }
}

__attribute__((optimize("-O3")))
void down(int x)
{
    int mb=0;
    while (x<tot)
    {
        if (x*2<=tot)
        {
            if (x*2+1<=tot)
            {
                if (d[x*2]>d[x*2+1]) mb=x*2+1; else mb=x*2;
            }
            else
            {
                mb=x*2;
            }
        }
        else break;
        if (d[x]>d[mb]) 
        {
            swap(d[x],d[mb]);x=mb;
        }
        else break;
    }
}

int main()
{
    freopen("triple.in","r",stdin);
    freopen("triple.out","w",stdout);
    scanf("%lld%lld%lld",&X,&Y,&Z);
    for (int i=1;i<=X+Y+Z;i++)
    {
        x[i]=read();y[i]=read();z[i]=read(); 
        sum+=x[i];
        a[i].y=y[i]-x[i];
        a[i].z=z[i]-x[i];
        a[i].x=a[i].y-a[i].z;
    }
    qsort(1,X+Y+Z);
    tot=0;
    for (int i=1;i<=Y;i++)
    {
        d[++tot]=a[i].y;
        up(tot);
        ansy[Y]+=a[i].y;
    }
    int n=X+Y+Z;
    for (int i=Y+1;i<=n;i++)
    {
        ansy[i]=ansy[i-1];
        if (d[1]<a[i].y)
        {
            ansy[i]=ansy[i]-d[1]+a[i].y; 
            d[1]=a[i].y;
            down(1);
        }
    }
    tot=0;
    for (int i=n;i>=n-Z+1;i--)
    {
        d[++tot]=a[i].z;
        up(tot);
        ansz[n-Z+1]+=a[i].z;
    }   
    for (int i=n-Z;i>=1;i--)
    {
        ansz[i]=ansz[i+1];
        if (d[1]<a[i].z)
        {
            ansz[i]=ansz[i]-d[1]+a[i].z; 
            d[1]=a[i].z;
            down(1);
        }
    }
    answer=0;
    for (int i=Y;i<=n-Z;i++)
    {
        answer=max(answer,sum+ansy[i]+ansz[i+1]);
    }
    printf("%lld\n",answer);
}

Guess you like

Origin www.cnblogs.com/RainbowCrown/p/11600520.html