BZOJ 4430 Guessing Camels賭駱駝
阿新 • • 發佈:2017-11-03
const blog sizeof for light -1 getc string query
【題意概述】
給出三個n的排列,求有多少個數對在三個排列中順序相同
【題解】
考慮用補集轉化的方法,答案為總對數-不滿足的對數
一對數不滿足條件,當且僅當這對數在兩個排列中順序相同,在另一個排列中的順序不同。
統計兩兩之間不滿足偏序條件的數對的個數,那麽每對數都被統計了兩次
#include<cstdio> #include<algorithm> #include<cstring> #define LL long long using namespace std; const int maxn=200010; int n,a[4][maxn],b[maxn],t[maxn]; LL ans,tmp; void read(int &k){ k=0; int f=1; char c=getchar(); while(c<‘0‘||c>‘9‘)c==‘-‘&&(f=-1),c=getchar(); while(‘0‘<=c&&c<=‘9‘)k=k*10+c-‘0‘,c=getchar(); k*=f; } void add(int x){for(;x<=n;x+=(x&-x)) t[x]++;} int query(int x){int ret=0; for(;x>0;x-=(x&-x)) ret+=t[x]; return ret;} int main(){ read(n); for (int j=1;j<=3;j++) for (int i=1;i<=n;i++) read(a[j][i]); for (int i=1;i<3;i++) for (int j=i+1;j<=3;j++){ memset(t,0,sizeof(t)); tmp=0; for (int k=1;k<=n;k++) b[a[i][k]]=k; for (int k=1;k<=n;k++) a[j][k]=b[a[j][k]]; for (int k=1;k<=n;k++) tmp+=query(a[j][k]),add(a[j][k]); ans+=1LL*n*(n-1)/2-tmp; } return printf("%lld\n",1LL*n*(n-1)/2-ans/2),0; }
BZOJ 4430 Guessing Camels賭駱駝