这个题给你一堆树,每棵树的位置x和高度h都给你
f[i]代表这棵树的位置排名,s[i]代表这棵树的高度排名
问你任意两棵树的(f[i] - f[j])*min(s[i],s[j])和
(f[i]-f[i-1])*min(s[i],s[i-1]) + (f[i]-f[i-2])*min(s[i],s[i-2])
首先看看暴力,肯定过不去,毕竟n2复杂度
看这个式子,其实比s[i]大的那么多项都能合并
合并成 ((f[i] - f[i-1])+ (f[i] - f[i-2]) +.....)*s[i]
所以只要在尽快的时间内求出(f[i] - f[i-1] + f[i] - f[i-2] ........)
f[i]是第i棵数的坐标排名
基本就是区间求和 求出小于f[i]的有多棵树 求出小于f[i]的树的坐标和
创建两个树状数组,非别维护坐标和 and 前面树的数量
复杂度就是nlogn了
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> using namespace std; const int maxn = 1e6+5; struct node { long long x,h; int p1,p2; } arr[maxn]; int c[maxn]; int d[maxn]; int n; bool cmp2(node a,node b); bool cmp1(node a,node b); long long getsumd(int i); long long getsumc(int i); void addc(long long i,long long j); void addd(long long i,long long j); int main() { int m,i,j,k; while (scanf("%d",&n) != EOF) { memset(c, 0, sizeof(c)); memset(d, 0, sizeof(d)); for(i=1;i<=n;++i) scanf("%lld%lld",&arr[i].x,&arr[i].h); sort(arr+1,arr+n+1,cmp1); arr[1].p1 = 1; for(i=2;i<=n;++i) { if(arr[i].x == arr[i-1].x) arr[i].p1 = arr[i-1].p1; else arr[i].p1 = i; } sort(arr+1,arr+1+n,cmp2); arr[1].p2 = 1; for(i=2;i<=n;++i) { if(arr[i].h == arr[i-1].h) arr[i].p2 = arr[i-1].p2; else arr[i].p2 = i; } for(i=1;i<=n;++i) { addc(arr[i].p1,arr[i].p1); addd(arr[i].p1, 1); } long long maxnn=0; for(i=1;i<=n;++i) { long long k1 = (getsumd(arr[i].p1))*arr[i].p1 - getsumc(arr[i].p1); //printf("%lld %lld ",getsumc(n)-getsumc(arr[i].p1),(getsumd(n) - getsumd(arr[i].p1))*arr[i].p1); k1 += (getsumc(n)-getsumc(arr[i].p1)) - (getsumd(n) - getsumd(arr[i].p1))*arr[i].p1; maxnn+=k1*arr[i].p2; addc(arr[i].p1, -arr[i].p1); addd(arr[i].p1, -1); } printf("%lld ",maxnn); } } long long lowbit(long long k) { return k&(-k); } void addc(long long i,long long j) { while(i<=n) { c[i]+=j; i+=lowbit(i); } } void addd(long long i,long long j) { while(i<=n) { d[i]+=j; i+=lowbit(i); } } long long getsumc(int i) { long long su = 0; while(i>0) { su+=c[i]; i-=lowbit(i); } return su; } long long getsumd(int i) { long long su = 0; while(i>0) { su+=d[i]; i-=lowbit(i); } return su; } bool cmp1(node a,node b) { if(a.x<b.x) return true; return false; } bool cmp2(node a,node b) { if(a.h<b.h) return true; return false; }