Contest题解逆序对
Contest
https://ac.nowcoder.com/acm/problem/13947
这题很厉害 我读了很久才真正的搞懂题意,答案+1的情况是 任意一组a,b队必须三次比赛中a任何一次至少排名大于b一次和bd大于a一次,这样两个才算一次,那么是不是我们就可以把a第一次排序 然后后面的就是 查找第二次的逆序对啦,但是有三次比赛,我们是不是需要选择任意两次 那就是C(n,2),对吧 ,组合一下(1.2)(1,3)(2,3),那么是不是就是直接求逆序对的数然后最后>>1
还有一件事 不知道如何使用树状数组来求逆序对的可以百度一下,然后我是看这个大佬的看懂的 谢谢大佬,
https://blog.nowcoder.net/n/41e0d9ce2e3543fab11fe0fd272df451
#include <bits/stdc++.h> #define fio ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0); #define debug(x) cout << #x << ": " << x << endl; #define debug1(x) cout<<"xxx"<<endl; #define ll long long #define ull unsigned long long #pragma GCC optimize("Ofast","inline","-ffast-math") #pragma GCC target("avx,sse2,sse3,sse4,mmx") #define mse(a,b) memset(a,b,sizeof a); #define fro for #define it int using namespace std; const int maxx=1e6+100; const int mod=1e9+7; ll qpow(ll a, ll b) { ll ans = 1; while (b) { if (b & 1) ans *= a; b >>= 1; a *= a; } return ans; } ll qpow(ll a, ll b, ll mod) { ll ans = 1; while (b) { if (b & 1)(ans *= a) %= mod; b >>= 1; (a *= a) %= mod; }return ans % mod; } inline ll read() { ll s = 0, w = 1; char ch = getchar(); for (; !isdigit(ch); ch = getchar()) if (ch == '-') w = -1; for (; isdigit(ch); ch = getchar()) s = (s << 1) + (s << 3) + (ch ^ 48); return s * w; } struct node{ int a,b,c; bool operator < (const node aa) { return a<aa.a; } }nod[maxx]; int evis[maxx]; void add(int x){ for(;x<maxx;x+=x&(-x)) evis[x]++; } int get_sum(int x){ ll sum=0; for(;x;x-=x&(-x)) sum+=evis[x]; return sum; } int main(){ fio; int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d%d%d",&nod[i].a,&nod[i].b,&nod[i].c); sort(nod+1,nod+1+n,[](node a,node b){ return a.a<b.a; }); ll sum=0; for(int i=1;i<=n;i++) add(nod[i].b),sum+=i-get_sum(nod[i].b); memset(evis,0,sizeof evis); for(int i=1;i<=n;i++) add(nod[i].c),sum+=i-get_sum(nod[i].c); memset(evis,0,sizeof evis); sort(nod+1,nod+1+n,[](node a,node b){ return a.b<b.b; }); for(int i=1;i<=n;i++) add(nod[i].c),sum+=i-get_sum(nod[i].c); printf("%lld",sum/2); return 0; }