1. 程式人生 > >World is Exploding (容斥 + 統計)

World is Exploding (容斥 + 統計)

  題意:滿足題目中的式子,a < b && c < d && Va < Vb && Vc > Vd

  思路:先求不討論位置重合的情況,把對應的2種關係相乘,然後得到的答案減去重合的地方。不想解釋,我特麼改著改著就對了。都不知道哪裡錯了,叫對了資料還是找不到。因為只有一組資料出錯。

#include<bits/stdc++.h>
using namespace std;

const int maxn = 5e4 + 7;
int tr[maxn], in[maxn], sar[maxn], ls[maxn], lb[maxn], rs[maxn], rb[maxn];
int n, m; int lowbit(int x){ return x & -x; } void add(int x, int d){ while(x <= n){ tr[x] += d; x += lowbit(x); } } int query(int x){ int ret = 0; while(x){ ret += tr[x]; x -= lowbit(x); } return ret; } int main(){ while(~scanf("
%d", &n)){ long long ans = 0, sum1 = 0, sum2 = 0; for(int i = 1; i <= n; i ++) scanf("%d", &in[i]), sar[i] = in[i]; sort(sar + 1, sar + n + 1); m = unique(sar + 1, sar + n + 1) - sar; for(int i = 1; i <= n; i ++) in[i] = lower_bound(sar + 1
, sar + n + 1, in[i]) - sar; memset(tr, 0, sizeof(tr)); for(int i = 1; i <= n; i ++){ ls[i] = query(in[i] - 1); lb[i] = query(n) - query(in[i]); sum1 += ls[i]; sum2 += lb[i]; add(in[i], 1); } for(int i = 1; i <= n; i ++){ rs[i] = query(in[i] - 1); rb[i] = query(n) - query(in[i]); add(in[i], -1); } ans = sum1 * sum2; for(int i = 1; i <= n; i ++){ ans -= 1LL * ls[i] * lb[i]; ans -= 1LL * ls[i] * rs[i]; ans -= 1LL * rb[i] * lb[i]; ans -= 1LL * rs[i] * rb[i]; } printf("%lld\n",ans); } return 0; }