Codeforces 1016 E

E - Rest In The Shades

思路:

相似

红色的长度等于(y - s) /  y 倍的 A' 和 B' 之间的 fence的长度

A' 是 p 和 A 连线和 x 轴交点, B'同理

交点也可以用相似求,然后lower_bound找到交点在哪里,然后通过预处理的fence长度的前缀和就可以求了,处理好边界

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define pdd pair<double, double>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout);
//head

const int N = 2e5 + 5;
pdd f[N];
double sum[N];
int main() {
    int n, q, l, r;
    double s, a, b, x, y;
    scanf("%lf %lf %lf", &s, &a, &b);
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) scanf("%lf %lf", &f[i].fi, &f[i].se);
    sum[0] = 0;
    for (int i = 1; i <= n; i++) {
        sum[i] = sum[i-1] + f[i].se - f[i].fi;
    }
    scanf("%d", &q);
    while(q--) {
        scanf("%lf %lf", &x, &y);
        double c1 = (a*y - s*x)/(y - s);
        double c2 = (b*y - s*x)/(y - s);
        int t = lower_bound(f+1, f+n+1, pdd(c1, 0)) - f;
        double ans = 0;
        if(t == 1) l = 1;
        else {
            l = t;
            if(c1 < f[t-1].se) ans += f[t-1].se - c1;
        }
        int tt = lower_bound(f+1, f+n+1, pdd(c2, 0)) - f;
        if(tt == 1) r = tt-1;
        else {
            r = tt-1;
            if(c2 < f[tt-1].se) ans -= f[tt-1].se - c2;
        }
        if(r >= l) ans += sum[r] - sum[l-1];
        printf("%.10f
", ans * (y - s) / y);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/widsom/p/9453494.html