[Fill file] noip2019 training test events (xv)

Problem A: conveyor belt

Time Limit: 1000 ms Memory Limit: 256 MB

Description

There is a two-dimensional plane on a conveyor belt, each belt can be regarded as one segment. Two conveyor belts are line segments AB and CD. Small moving speed on the y AB is P, the moving speed on the CD is Q, the speed of movement in the plane R. Now, the small y would go from point A to point D, does he need to go at least how long.

Input

The first row is an integer of 4, a graph of A and B, respectively, Ax, Ay, Bx, By.

The second line is the integer 4, a graph C and D, respectively, Cx, Cy, Dx, Dy.

The third line is an integer of 3, are P, Q, R.

Output

An output line number, y represents a small minimum time go from point A to point D, reserved to two decimal places.

Sample Input
0 0 0 100
100 0 100 100
2 2 1 
Sample Output
136.60

HINT

For 30% of the data satisfies:

1<=Ax,Ay,Bx,By,Cx,Cy,Dx,Dy<=10

1<=P,Q,R<=5

To 100% of the data satisfies:

1<=Ax,Ay,Bx,By,Cx,Cy,Dx,Dy<=1000

1<=P,Q,R<=10

Solution

Third of the board problem?

First third of the distance from the starting point and A, and then set a three-point calculated from a starting point to a point of minimum distance to the CD.

#include<bits/stdc++.h>
using namespace std;
const double eps=1e-4;
struct point{
    double x,y;
    point(){}
    point(double xx,double yy){x=xx,y=yy;}
}A,B,C,D;
double AB,CD;
double p,q,r;
point operator +(point a,point b){
    return point(a.x+b.x,a.y+b.y);
}
point operator -(point a,point b){
    return point(a.x-b.x,a.y-b.y);
}
point operator *(point a,double k){
    return point(a.x*k,a.y*k);
}
double dis(point a,point b){
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double cal(point X,double x){
    point tmp=C;
    if(CD!=0.0){
        tmp=(C+(D-C)*(x/CD));
    }
    return dis(X,tmp)/r+(CD-x)/q;
}
double calc(double x){
    point tmp=A;
    if(AB!=0.0){
        tmp=(A+(B-A)*(x/AB));
    }
    double l=0,r=CD;
    while(r-l>eps){
        double mid=(l+r)/2.0;
        double m1=(mid-eps/2.0),m2=(mid+eps/2.0);
        if(cal(tmp,m1)<=cal(tmp,m2)){
            r=mid;
        }
        else l=mid;
    }
    return x/p+cal(tmp,(l+r)/2.0);
}
int main(){
    scanf("%lf%lf%lf%lf",&A.x,&A.y,&B.x,&B.y);
    scanf("%lf%lf%lf%lf",&C.x,&C.y,&D.x,&D.y);
    scanf("%lf%lf%lf",&p,&q,&r);
    AB=dis(A,B),CD=dis(C,D);
    double l=0,r=AB;
    while(r-l>eps){
        double mid=(l+r)/2.0;
        double m1=(mid-eps/2.0),m2=(mid+eps/2.0);
        //cout<<calc(m1)<<" "<<calc(m2)<<endl; 
        if(calc(m1)<=calc(m2)){
            r=mid;
        }
        else l=mid;
    }
    //printf("%.2lf\n",(l+r)/2.0);
    printf("%.2lf\n",calc((l+r)/2.0));
}

Problem B: crazy Vulcan

Time Limit: 1000 ms Memory Limit: 256 MB

Description

Vulcan To test the power zone, he decided singled n people.

Vulcan due to the limited training time, only a maximum of t minutes, so he can choose to be a part of people singled out because of helpful small y, he got everyone's specific value of each person's value consists of a triplet (a, b, c) composition, said that if the Vulcan in the first x minutes singled this man, he will get experience ab * x, and he needs to defeat the c-minute man.

Vulcan now want to know how much experience he can get up to, due to the inherently stupid Vulcan, god of fire into the zone of crazy even stupid, so he wants you to help him figure out how much experience he can get up to .

Input

The first line of a positive integer T, denotes the number of data sets.

For each test, the behavior of the first two positive integers n and t, represents the person's training time with the number of singled out and Vulcan Vulcan. The following n lines of three positive integers Ai, Bi, Ci, represents the value of each person, and see the meaning of the title.

Output

For each data output line an integer representing the maximum number of Vulcan experience can be obtained.

Sample Input
1
4 10
110 5 9
30 2 1
80 4 8
50 3 2 
Sample Output
88

HINT

For 20% of the data satisfies: 1≤n≤10

For 50% of the data satisfies: 1≤n≤18

To 100% of the data satisfies: 1≤n≤1000,1≤t≤3000,1≤Ci≤t, Ai≤10 ^ 6

To ensure that n> the number of data group 200 does not exceed five groups, the number of data sets other group does not exceed 10

Ensure that each person's contribution to the end of the training experience will not become negative

Solution

IMHO subject description is a lump of shit!

Calculate the value of his experience acquired is considered after the defeat of.

For some time to consider how the current election to maximize their experience acquired.

Because experience will over time, so for any combination of a choice, it must be subtracted more preferences.

Proof: two of them set value of b and c values are \ (B1, C1, B2, C2 \) , and there \ ({b1 \ over c1} > {b2 \ over c2} \)

If you let the 1 in front of the experience is lost \ (b1 \ Times c1 + b2 \ Times (c1 + c2) \) , otherwise \ (b2 \ times c2 + b1 \ times (c1 + c2) \)

Both sides subtract \ (b1 \ Times c1 + b2 \ Times c2 \) , is left to \ (b2 \ times c1 \) and $ b1 \ times c2 $

Binding uppermost formula can be obtained \ (b2 \ times c1 <b1 \ times c2 \)

We need to ensure a top surface.

So we sort and then directly to a single DP backpack according to c / b.

#include<bits/stdc++.h>
using namespace std;
struct sb{
    int a,b,c;
}a[200001];
bool operator <(sb x,sb y){
    return x.c*1ll*y.b<x.b*1ll*y.c;
}
int dp[200001];
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        memset(dp,0,sizeof(dp));
        int n,t;
        scanf("%d%d",&n,&t);
        for(int i=1;i<=n;++i){
            scanf("%d%d%d",&a[i].a,&a[i].b,&a[i].c);
        }
        sort(a+1,a+1+n);
        //for(int i=1;i<=n;++i){
            //cout<<a[i].a<<" "<<a[i].b<<" "<<a[i].c<<endl;
        //}
        for(int i=1;i<=n;++i){
            for(int j=t-a[i].c;~j;--j){
                //cout<<j<<endl;
                dp[j+a[i].c]=max(dp[j+a[i].c],dp[j]+a[i].a-(a[i].b*(j+a[i].c)));
            }
        }
        int ans=0;
        for(int i=0;i<=t;++i)ans=max(ans,dp[i]);
        printf("%d\n",ans);
    }
}

Problem C: Vulcan fish

Time Limit: 5000 ms Memory Limit: 256 MB

Description

Vulcan favorite is fish, so one day he came to a pond fishing. Pond can be regarded as a two-dimensional plane, and his fishing net can be seen as a rectangle parallel to the coordinate axes.

Pond fish kept swimming in the water, it can be seen at some point. Sometimes the fish will swim into the nets, sometimes there will be fish swim out fishing nets. So Vulcan do not know when the net can catch the most fish, and now he seeks your help.

He pond each fish are given a label, respectively, from grade 1 to n, n represents the total number of fish in the pond. Fish swimming can be summarized in two actions:

1 lrd: represents a numeral in the fish [l, r] of this interval d of the floating unit length in the positive x-axis direction.

2 lrd: represents a numeral in [l, r] the fish swimming in the interval d of the unit length in the y-axis positive direction.

At some point, Vulcan will ask you now how many fish in the nets (also count on the border), please come help him.

Input

The first row contains an integer T, represents a set of test data. For each set of test data:

The first row contains an integer n, the total number of fish.

The second line contains four integers x1, y1, x2, y2, top right and bottom left corner coordinates in the coordinate nets.

Next n lines of two integers xi, yi, fish symbols indicating the coordinates of the initial time i.

The next line contains an integer m, the latter represents the number of events.

The next m lines, each one of three types of behavior:

1 lrd: represents a numeral in the fish [l, r] of this interval d of the floating unit length in the positive x-axis direction.

2 lrd: represents a numeral in [l, r] the fish swimming in the interval d of the unit length in the y-axis positive direction.

3 lr: Inquiry Now numerals represent [l, r] in the fish in this section how many nets.

Output

For each set of data in each interrogation, to output a corresponding answer integer.

Sample Input
1
5
1 1 5 5
1 1
2 2
3 3
4 4
5 5
3
3 1 5
1 2 4 2
3 1 5 
Sample Output
5
4

HINT

For 30% of the data satisfies: 1≤n, m≤1000

To 100% of the data satisfies: 1≤T≤10,1≤n, m≤30000,1≤l≤r≤n, 1≤d≤10 ^ 9, x1≤x2, y1≤y2. To ensure that all the coordinate values ​​according to an arbitrary time within the range [-10 ^ 9 ^ 9,10].

Solution

We planted two tree line, an x ​​coordinate of each point of maintenance, a maintenance y coordinates.

So minx matrix x coordinate of the lower left corner, maxx is the x-coordinate of the upper right corner of the matrix, miny, minx empathy.

After three minutes for each coordinate :( here just write x coordinate, y coordinate and so on)

1, x <minx this case we look at his record the distance to the minx, and then subtracted from each modification put the corresponding number is less than 0, we classify it to the second category.

2, minx <= x <= maxx case of recording his distance maxx, supra changes, and for this point detection section: if it satisfies y coordinates in the matrix, we answer +1. If the distance is less than 0, go to the third category.

3, maxx <x us directly from this set inf enough, then no matter.

Min value for each interval, as long as the modification is less than zero, we recount the answer to this interval.

Recount answer when a tree with an array of records to see if you can do at each point in the matrix \ (O (log n) \ ) is asked.

As each point is greater than maxx long as we on the matter, so each point in fact it will only update 2 times for a total modification complexity is \ (O (n log n) \) is.

But I do not know how to write or ugly, because it is rubbing off time, won the slowest.

#include<bits/stdc++.h>
using namespace std;
inline int read(){
    int x=0;bool f=1;char c=getchar();
    for(;!isdigit(c);c=getchar())if(c=='-')f=0;
    for(;isdigit(c);c=getchar())x=(x<<3)+(x<<1)+(c^'0');
    if(f)return x;return 0-x;
}
#define INF 2147483647
inline int lowbit(int x){return x&-x;}
int n;
int bit[200001];
inline void add(int x,int v){
    while(x<=n){
        bit[x]+=v;
        x+=lowbit(x);
    }
}
inline int query(int x){
    int res=0;
    while(x){
        res+=bit[x];
        x-=lowbit(x); 
    }
    return res;
} 
int op[2][2];
int pos[200001][2];
bool in[200001];
struct seg{
    int type;
    int minn[200001];
    int tag[200001];
    inline void change(int o,int l){
        add(l,-in[l]);
        in[l]=(pos[l][0]>=op[0][0]&&pos[l][0]<=op[0][1]&&pos[l][1]>=op[1][0]&&pos[l][1]<=op[1][1]);
        add(l,in[l]);
        if(pos[l][type]<op[type][0])minn[o]=op[type][0]-pos[l][type];
        else if(pos[l][type]<=op[type][1])minn[o]=op[type][1]-pos[l][type];
        else minn[o]=INF;
    }
    void build(int o,int l,int r){
        tag[o]=0;
        if(l==r){
            change(o,l);
            return;
        }
        int mid=(l+r)/2;
        build(o*2,l,mid);
        build(o*2+1,mid+1,r);
        minn[o]=min(minn[o*2],minn[o*2+1]);
    }
    void pushdown(int o){
        tag[o*2]+=tag[o],tag[o*2+1]+=tag[o];
        minn[o*2]-=tag[o],minn[o*2+1]-=tag[o];
        tag[o]=0; 
    }
    void update(int o,int l,int r){
        if(l==r){
            pos[l][type]+=tag[o];
            tag[o]=0;
            change(o,l);
            return;
        }
        pushdown(o);
        int mid=(l+r)/2;
        update(o*2,l,mid);
        update(o*2+1,mid+1,r);
        minn[o]=min(minn[o*2],minn[o*2+1]);
    }
    void modify(int o,int l,int r,int L,int R,int val){
        if(L<=l&&r<=R){
            tag[o]+=val;
            minn[o]-=val;
            if(minn[o]<=0)update(o,l,r);
            return;
        }
        pushdown(o);
        int mid=(l+r)/2;
        if(L<=mid)modify(o*2,l,mid,L,R,val);
        if(mid<R)modify(o*2+1,mid+1,r,L,R,val);
        minn[o]=min(minn[o*2],minn[o*2+1]);
    }
}t[2];
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        memset(in,0,sizeof(in));
        memset(bit,0,sizeof(bit));
        n=read();
        op[0][0]=read(),op[1][0]=read(),op[0][1]=read(),op[1][1]=read();
        for(int i=1;i<=n;++i){
            pos[i][0]=read(),pos[i][1]=read();
        }
        t[0].type=0;
        t[1].type=1;
        t[0].build(1,1,n);
        t[1].build(1,1,n);
        int m;
        m=read();
        for(int i=1;i<=m;++i){
            int opt=read();
            if(opt==3){
                int l=read(),r=read();
                printf("%d\n",query(r)-query(l-1));
            }
            else {
                int l=read(),r=read(),val=read();
                t[opt-1].modify(1,1,n,l,r,val);
            }
        }
    }
} 

Guess you like

Origin www.cnblogs.com/youddjxd/p/11423233.html