1. 程式人生 > >283E&EZOJ #89 Cow Tennis Tournament

283E&EZOJ #89 Cow Tennis Tournament

com struct cout algo ctype i++ iostream sum nod

傳送門

分析

我們考慮用所有的情況減去不合法的情況

不難想出所有情況為$C_n^3$

於是我們考慮不合法的情況

我們知道對於一個不合法的三元組$(a,b,c)$一定是修改後$a<b,b>c$

於是我們可以離散化後用線段樹維護每個點被覆蓋了幾次

所以每次對於一個點$i$,比它大的點的個數即為在它前面修改次數為偶數的數量加在它後面修改次數為奇數的數量

而產生的不合法情況即為$C_{sum_i}^2$

我們再統計前後兩種情況的時候將修改排序然後分別從後往前和從前往後各跑一次即可

每次只要區間不再覆蓋點$i$則統計答案

代碼

#include<iostream>
#include
<cstdio> #include<cstring> #include<string> #include<algorithm> #include<cctype> #include<cmath> #include<cstdlib> #include<queue> #include<ctime> #include<vector> #include<set> #include<map> #include<stack> using namespace
std; struct node { long long le,ri; }; node q[100100]; long long d[400100],col[400100],n,m; long long a[100100],sum[100100]; vector<long long>id; inline bool cmp1(const node x,const node y){ return x.le==y.le?x.ri<y.ri:x.le<y.le; } inline bool cmp2(const node x,const node y){ return x.ri==y.ri?x.le>y.le:x.ri>y.ri; } inline
void update(long long le,long long ri,long long wh,long long x,long long y){ if(x>y)return; if(le>=x&&ri<=y){ col[wh]^=1; d[wh]=(ri-le+1)-d[wh]; return; } long long mid=(le+ri)>>1; if(col[wh]){ col[wh<<1]^=1; col[wh<<1|1]^=1; d[wh<<1]=(mid-le+1)-d[wh<<1]; d[wh<<1|1]=(ri-mid)-d[wh<<1|1]; col[wh]=0; } if(mid>=x)update(le,mid,wh<<1,x,y); if(mid<y)update(mid+1,ri,wh<<1|1,x,y); d[wh]=d[wh<<1]+d[wh<<1|1]; } inline long long Q(long long le,long long ri,long long wh,long long x,long long y){ if(x>y)return 0; if(le>=x&&ri<=y)return d[wh]; long long mid=(le+ri)>>1,ans=0; if(col[wh]){ col[wh<<1]^=1; col[wh<<1|1]^=1; d[wh<<1]=(mid-le+1)-d[wh<<1]; d[wh<<1|1]=(ri-mid)-d[wh<<1|1]; col[wh]=0; } if(mid>=x)ans+=Q(le,mid,wh<<1,x,y); if(mid<y)ans+=Q(mid+1,ri,wh<<1|1,x,y); d[wh]=d[wh<<1]+d[wh<<1|1]; return ans; } int main(){ long long i,j,k; scanf("%lld%lld",&n,&m); for(i=1;i<=n;i++)scanf("%lld",&a[i]),id.push_back(a[i]);; sort(id.begin(),id.end()); id.erase(unique(id.begin(),id.end()),id.end()); for(i=1;i<=m;i++) scanf("%lld%lld",&q[i].le,&q[i].ri); sort(q+1,q+m+1,cmp1); long long Ans=n*(n-1)*(n-2)/6; j=1; for(i=1;i<=m;i++){ for(j;j<=lower_bound(id.begin(),id.end(),q[i].le)-id.begin();j++) sum[j]+=(n-j)-Q(1,n,1,j+1,n); update(1,n,1,lower_bound(id.begin(),id.end(),q[i].le)-id.begin()+1, upper_bound(id.begin(),id.end(),q[i].ri)-id.begin()); } for(j;j<=n;j++)sum[j]+=(n-j)-Q(1,n,1,j+1,n); memset(d,0,sizeof(d)); memset(col,0,sizeof(col)); sort(q+1,q+m+1,cmp2); j=n; for(i=1;i<=m;i++){ for(j;j>=upper_bound(id.begin(),id.end(),q[i].ri)-id.begin()+1;j--) sum[j]+=Q(1,n,1,1,j-1); update(1,n,1,lower_bound(id.begin(),id.end(),q[i].le)-id.begin()+1, upper_bound(id.begin(),id.end(),q[i].ri)-id.begin()); } for(j;j>0;j--)sum[j]+=Q(1,n,1,1,j-1); for(i=1;i<=n;i++)Ans-=sum[i]*(sum[i]-1)/2; cout<<Ans; return 0; }

283E&EZOJ #89 Cow Tennis Tournament