思路:
相似
红色的长度等于(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; }