标签:blog http io os ar for sp 数据 div
我就不说我很sb的用线段树来维护值。。。。。。
本机自测的时候想了老半天没想出怎么维护点在所有区间被多少区间包含的方法。最后一小时才想出来线段树(果然太弱)
。。
首先想到贪心,答案一定是某个区间的右端点。。。(这个很容易想也容易证,我就不说了。。。。。)
然后按右端点排序
然后我维护了个左端点前缀和,将来枚举每一个右端点的时候所得到的答案就是sum[n]-sum[i]-he+ge*a[i].r
he表示包含右端点的所有区间的左端点之和,ge表示包含这个点的区间个数。(均不包括自己)
。。
然后离散一下端点用线段树就可以维护he和ge了。。。。
。。
噗,为嘛我没想到直接差分就行了。。。。。。。。
我们直接枚举每个端点,然后维护一个左端点的(后缀和,应该这么说对吧。。。。),每遇到一个左端点就剪掉,就是he,ge数就++同理。。。。。
遇到右端点ge就--且更新答案。QAQ
然后就行了。。
#include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <algorithm> #include <string> using namespace std; typedef long long ll; const int max(const int &a, const int &b) { return a>b?a:b; } const int min(const int &a, const int &b) { return a<b?a:b; } #define read(x) scanf("%d", &x) #define error(x) if(x) { puts("error"); } #define dbg(x) cout << (#x) << " = " << x << endl #define rep(i, n) for(int i=0; i<n; ++i) #define for1(i,a,n) for(int i=(a); i<=(n); ++i) #define for2(i,a,n) for(int i=(a); i<(n); ++i) #define for3(i,a,n) for(int i=(a); i>=(n); ++i) #define for4(i,a,n) for(int i=(a); i>(n); ++i) #define lc x<<1 #define rc x<<1|1 #define lson l, m, lc #define rson m+1, r, rc #define MID (l+r)>>1 const int N=1e5+10; struct dat { ll l, r; int pl, pr; }a[N]; struct Tre { int s; ll sum; }t[N<<4]; void pushup(int x) { t[x].s=t[lc].s+t[rc].s; t[x].sum=t[lc].sum+t[rc].sum; } void update(int l, int r, int x, int pos, ll sum, int k) { if(l==r) { t[x].s+=k; t[x].sum+=sum; return; } int m=MID; if(pos<=m) update(lson, pos, sum, k); else update(rson, pos, sum, k); pushup(x); } int ask1(int l, int r, int x, int L, int R) { if(L<=l && r<=R) return t[x].s; int m=MID, ret=0; if(L<=m) ret+=ask1(lson, L, R); if(m<R) ret+=ask1(rson, L, R); return ret; } ll ask2(int l, int r, int x, int L, int R) { if(L<=l && r<=R) return t[x].sum; int m=MID; ll ret=0; if(L<=m) ret+=ask2(lson, L, R); if(m<R) ret+=ask2(rson, L, R); return ret; } bool cmp(const dat &a, const dat &b) { return a.r<b.r; } int n, num; ll sum[N], he, ans, E, ge, b[N<<1]; int main() { read(n); for1(i, 1, n) read(a[i].l), read(a[i].r), b[++num]=a[i].l, b[++num]=a[i].r; sort(a+1, a+1+n, cmp); sort(b+1, b+1+num); num=unique(b+1, b+1+num)-b-1; for1(i, 1, n) a[i].pl=lower_bound(b+1, b+1+num, a[i].l)-b; for1(i, 1, n) a[i].pr=lower_bound(b+1, b+1+num, a[i].r)-b; for1(i, 1, n) update(1, num, 1, a[i].pl, a[i].l, 1); for1(i, 1, n) sum[i]=sum[i-1]+a[i].l; for1(i, 1, n) { update(1, num, 1, a[i].pl, -a[i].l, -1); while(a[i].r==a[i+1].r) { ++i; update(1, num, 1, a[i].pl, -a[i].l, -1); } ge=ask1(1, num, 1, 1, a[i].pr); he=ask2(1, num, 1, 1, a[i].pr); ll tp=sum[n]-sum[i]-he+ge*a[i].r+a[i].r; if(tp>ans) { ans=tp; E=a[i].r; } } printf("%lld %lld\n", E, ans); return 0; }
2
5 10
20 25
10 30
【tyvj】P2065 「Poetize10」封印一击(贪心+线段树/差分)
标签:blog http io os ar for sp 数据 div
原文地址:http://www.cnblogs.com/iwtwiioi/p/4051439.html