noip2019トレーニングテストイベント(XV)[ファイルを塗りつぶし]

問題A:コンベヤーベルト

制限時間:1000msのメモリ制限:256メガバイト

説明

コンベヤベルト上の2次元平面であり、各ベルトは一つのセグメントとみなすことができます。二つのコンベアベルトは、線分ABとCDです。Y AB上の小さな移動速度がPであり、CD上の移動速度は、Q、平面Rの移動速度であります さて、小さなyはDを指すように、点Aから行くと、彼は少なくともどのくらい行く必要がありません。

入力

最初の行は、4の整数であり、A及びBのグラフ、それぞれ、AX、Ayの、BX、によるものです。

2行目は整数4、グラフCおよびDはそれぞれ、Cxとは、Cy、Dxを、Dyのです。

三行目は、3の整数であり、P、Qであり、R.

出力

出力回線番号、yが小さい最小時間は、2つの小数点以下に予約点Dに点Aから行く表します。

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

ヒント

データ満足の30%。

1 <= AX、Ayの、BX、により、Cxのは、Cy、Dxを、Dyの<= 10

1 <= P、Q、R <= 5

データを満たすの100%に:

1 <= AX、Ayの、BX、により、Cxのは、Cy、Dxを、Dyの<= 1000

1 <= P、Q、R <= 10

溶液

ボードの問題のサード?

最初の出発点とAからの距離の三、およびCDへの最短距離の点に開始点から算出された3点を設定します。

#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));
}

問題B:クレイジーバルカン

制限時間:1000msのメモリ制限:256メガバイト

説明

パワーゾーンをテストするにはバルカンは、彼は、n人を選抜しました。

バルカンは、限られたトレーニング時間のために、唯一トン分の最大なので、彼は人々の一部であることを選択することができますが、彼は一人一人の価値のみんなの具体的な値は、(トリプレットで構成されていました、なぜなら役立つ小型のY白羽B、C)は、組成物、この男を選抜最初のx分でバルカンならば、彼は経験AB * xを取得します、と彼はC​​分の男を倒すために必要があると述べました。

バルカンは今、彼が原因本質的に愚かなバルカン、狂気さえ愚かのゾーンに火の神に、まで得ることができますどのように多くの経験を知りたいので、彼は彼が彼がまで取得することができますどのくらいの経験を見つけ出す手助けするためにあなたを望んでいます。

入力

正の整数Tの最初の行は、データセットの数を表します。

各テストでは、最初の2つの正の整数のnとtの挙動は、選抜やバルカンバルカンの数の人のトレーニング時間を表しています。3つの正の整数愛、ゲイ、CI、次のn行は、それぞれの人の値を示しており、タイトルの意味を参照してください。

出力

各データ出力ラインのためのバルカン経験の最大数を表す整数を得ることができます。

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

ヒント

1≤n≤10:データ満足の20%を

データ満足の50%:1≤n≤18

1≤n≤1000,1≤t≤3000,1≤Ci≤t、Ai≤10^ 6:データを満たすの100%に

データ群200の数は、5つのグループを超えていない>そのNを確保するために、データの数が10を超えていない他のグループを設定します

トレーニングの経験の終わりに、各個人の貢献はマイナスになることはありませんことを確認してください

溶液

私見対象説明はたわごとの塊です!

の敗北の後に考えられて取得経験値を計算します。

しばらくの間、現在の選挙は自分の経験を取得最大限にする方法を検討します。

経験が時間をかけて、選択した任意の組み合わせのためので、それはより多くの好みを差し引かなければならないからです。

bとcの値のうちの2つの設定値れる:プルーフ\(B1、C1、B2、C2 \)が、および\({C1上のB1 \} > {C2上のB2 \} \)

あなたが経験の前に1をさせた場合に失われるが、\(B1用の\タイムズC1 + B2 \タイムズ(C1 + C2)\) そうでない場合は、\(B2の\回数C2 + B1 \回(C1 + C2)\)

双方は、減算\(B1 \タイムズC1 + B2 \タイムズC2を\) させておく(\ B2の\時間c1は)\と時間C2 $ \ $ B1

最上式結合を得ることができる\(B2 \回C1 <B1 \回C2 \)

私たちは、上面を確保する必要があります。

だからソートして、直接、単一のDPのバックパックに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);
    }
}

問題C:バルカン魚

制限時間:5000ミリ秒のメモリ制限:256メガバイト

説明

バルカンの好きな魚なので、1日、彼は池釣りに来ました。池は、二次元平面とみなすことができ、そして彼の漁網を座標軸に矩形平行と見なすことができます。

池の魚は水の中で泳いで保管、それはいくつかの点で見ることができます。時々魚は時々魚は漁網をそこに泳ぐされます、ネットの中に泳ぐます。ネットはほとんどの魚をキャッチすることができ、そして今、彼はあなたの助けを求めるときにバルカンは知りません。

彼は池各魚をグレード1からnまで、それぞれ、ラベルを与えられ、nは池の魚の総数を表しています。泳ぐ魚は2つのアクションでまとめることができます。

1 LRDは:正のx軸方向に浮動単位長さのこの間隔dの魚[L、R]内の数字を表します。

2 LRD:Y軸正方向の単位長さの間隔dで泳ぐ魚[L、R]内の数字を表します。

ある時点で、バルカンは(も国境を頼りに)今、ネットでどのように多くの魚をお聞きします、彼を助けて来てください。

入力

最初の行は、整数のTを含む試験データのセットを表します。テストデータの各セットの場合:

最初の行は、整数n、魚の総数を含んでいます。

2行目は、X1、Y1、X2、Y2、右上と左下隅の座標をネットで座標4つの整数が含まれています。

二つの整数XI、YI、初期時間Iの座標を示す魚シンボルの次のn行。

次の行は、後者は、イベントの数を表す、整数mを含有します。

次のm行、動作の3種類のいずれか

1 LRDは:正のx軸方向に浮動単位長さのこの間隔dの魚[L、R]内の数字を表します。

2 LRD:Y軸正方向の単位長さの間隔dで泳ぐ魚[L、R]内の数字を表します。

3 LR:どのように多くのネット問い合わせ今数字は、このセクションで魚の[L、R]を表します。

出力

各質問のデータの各セット、出力に応じた回答整数ため。

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

ヒント

データ満足の30%:1≤n、m≤1000

1≤T≤10,1≤n、m≤30000,1≤l≤r≤n、1≤d≤10^ 9、x1≤x2、y1≤y2:データ満足の100%まで。すべての範囲内の任意の時間に応じて座標値ことを確認するために[-10 ^ 9 ^ 9,10]。

溶液

我々は、x、メンテナンスの各点の座標メンテナンスY座標、2本のツリーラインを植えました。

そうミンクス行列Xは左下隅の座標、MAXXは、マトリックス、MINY、ミンクスの共感の右上隅のx座標です。

後に各3分間座標:(ここでXだけ書き込み座標、y座標など)

1、X <このケースをMINX我々はミンクスに彼の記録で距離を見て、その後、各変更から差し引か対応する番号が0より小さい、我々は第二のカテゴリーに分類置きます。

2、ミンクス<= xは<= MAXX彼の距離MAXX、上記の変更を記録する場合、この点検出部のため:それは、Yはマトリックス座標満たしている場合、我々は+1に答えます。距離が0未満の場合、第三のカテゴリーに移動します。

3、MAXX <X私たちに直接十分なこのセットINFから、その後、どんなに。

各間隔の最小値は、限り修正がゼロ未満であると、私たちは、この間隔に対する答えを詳述します。

あなたは、マトリックス内の各ポイントで行うことができればレコードの配列を持つツリーが参照するには再集計の解答\(O(n個のログは)\ ) 頼まれます。

各点が問題に長い我々としてMAXX以上である、ように実際には各点は、それが唯一の総修正の複雑さのために2回を更新しますです\(O(nはn個のログ) \) です。

しかし、私はそれが時間をこすりされているので、最も遅い獲得した、醜い書いたりするのか分かりません。

#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);
            }
        }
    }
} 

おすすめ

転載: www.cnblogs.com/youddjxd/p/11423233.html