把没用的第一类区间去掉之后, 排序, 然后枚举第二类区间, 在上面死命二分就好了。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #define PLI pair<LL, int> #define PII pair<int, int> #define SZ(x) ((int)x.size()) #define ull unsigned long long using namespace std; const int N = 2e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-6; const double PI = acos(-1); bool chkmax(LL& a, LL b) { return a < b ? a = b, true : false; } bool chkmax(int& a, int b) { return a < b ? a = b, true : false; } int Log[N]; struct ST { PII dp[N][20]; void build(int n, PII b[]) { for(int i = 1; i <= n; i++) dp[i][0] = b[i]; for(int j = 1; j <= Log[n]; j++) for(int i = 1; i+(1<<j)-1 <= n; i++) dp[i][j] = max(dp[i][j-1], dp[i+(1<<(j-1))][j-1]); } PII query(int x, int y) { int k = Log[y - x + 1]; return max(dp[x][k], dp[y-(1<<k)+1][k]); } }; int n, m; PII len[N]; PII gg = mk(1, 1); pair<PII, int> a[N]; pair<PII, int> b[N]; ST rmq; bool cmp(const pair<PII, int>& a, const pair<PII, int>& b) { if(a.fi.fi == b.fi.fi) return a.fi.se > b.fi.se; return a.fi.fi < b.fi.fi; } int main() { for(int i = -(Log[0]=-1); i < N; i++) Log[i] = Log[i - 1] + ((i & (i - 1)) == 0); scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++) scanf("%d%d", &a[i].fi.fi, &a[i].fi.se), a[i].se = i; for(int i = 1; i <= m; i++) scanf("%d%d%d", &b[i].fi.fi, &b[i].fi.se, &b[i].se); sort(a + 1, a + 1 + n, cmp); int up = n; n = 1; for(int i = 1; i <= up; i++) if(a[i].fi.se > a[n].fi.se) a[++n] = a[i]; // for(int i = 1; i <= n; i++) printf("%d %d %d ^^ ", a[i].se, a[i].fi.fi, a[i].fi.se); for(int i = 1; i <= n; i++) len[i].fi = a[i].fi.se - a[i].fi.fi, len[i].se = a[i].se; rmq.build(n, len); LL ans = 0; for(int i = 1; i <= m; i++) { int L = b[i].fi.fi, R = b[i].fi.se, c = b[i].se, len = 0, who = 1; int low = 1, high = n, p = -1; while(low <= high) { int mid = low + high >> 1; if(a[mid].fi.fi <= L) p = mid, low = mid + 1; else high = mid - 1; } if(~p && a[p].fi.se > L && chkmax(len, min(R, a[p].fi.se) - L)) who = a[p].se; low = 1, high = n, p = -1; while(low <= high) { int mid = low + high >> 1; if(a[mid].fi.se >= R) p = mid, high = mid - 1; else low = mid + 1; } if(~p && a[p].fi.fi < R && chkmax(len, R - max(L, a[p].fi.fi))) who = a[p].se; int Lb = -1, Rb = -1; low = 1, high = n; while(low <= high) { int mid = low + high >> 1; if(a[mid].fi.fi >= L) Lb = mid, high = mid - 1; else low = mid + 1; } low = 1, high = n; while(low <= high) { int mid = low + high >> 1; if(a[mid].fi.se <= R) Rb = mid, low = mid + 1; else high = mid - 1; } if(~Lb && ~Rb && Lb <= Rb) { PII t = rmq.query(Lb, Rb); if(chkmax(len, t.fi)) who = t.se; } if(chkmax(ans, 1LL * c * len)) { gg.fi = who; gg.se = i; } } if(ans) { printf("%lld ", ans); printf("%d %d ", gg.fi, gg.se); } else { puts("0"); } return 0; } /* */