//矩阵,异或
//树套树
总方案数-不合法方案数
C(N,3) - 不存在一个环(有人能打赢另外两个)
第i个人能赢d[i]场
sum{C(d[i],2)}
C(N,3)-sum{C(d[i],2)}
问题转化成k次操作后,每人的情况
离线,把所有操作都读进来,进行一些处理
把所有操作记录下来,什么能力值开始出现反转,什么能力值结束反转
5~9 5,10
离散化//考试的时候打暴力没有注意到这个,所以一分没有
l[i]+1 r[i]-1
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<vector> 7 using namespace std; 8 #define ls (t<<1) 9 #define rs ((t<<1)|1) 10 typedef long long ll; 11 typedef pair<int,int>pii; 12 const int maxn=1e5+7; 13 const int INF=0x7f7f7f7f; 14 int n,k; 15 ll ans; 16 int s[maxn],sum[maxn<<2],lazy[maxn<<2];//线段树开4倍,2倍不够 17 vector<int>vl[maxn],vr[maxn]; 18 void push_up(int t){ 19 sum[t]=sum[ls]+sum[rs]; 20 } 21 void push_down(int t,int l,int r){ 22 if(lazy[t]){ 23 lazy[t]^=1; 24 lazy[ls]^=1;lazy[rs]^=1; 25 int mid=(l+r)/2; 26 sum[ls]=mid-l+1-sum[ls]; 27 sum[rs]=r-mid-sum[rs]; 28 } 29 } 30 void update(int L,int R,int l,int r,int t){ 31 if(L<=l&&r<=R){ 32 sum[t]=r-l+1-sum[t];//取反后和进行的操作 33 lazy[t]^=1; 34 return; 35 } 36 push_down(t,l,r); 37 int mid=(l+r)/2; 38 if(L<=mid) update(L,R,l,mid,ls); 39 if(R>mid) update(L,R,mid+1,r,rs); 40 push_up(t); 41 } 42 int query(int L,int R,int l,int r,int t){ 43 if(L<=l&&r<=R) return sum[t]; 44 push_down(t,l,r); 45 int mid=(l+r)/2,ret=0; 46 if(L<=mid) ret+=query(L,R,l,mid,ls); 47 if(R>mid) ret+=query(L,R,mid+1,r,rs); 48 return ret; 49 } 50 int main(){ 51 cin>>n>>k; 52 for(int i=0;i<n;i++) cin>>s[i]; 53 sort(s,s+n); 54 while(k--){ 55 int l,r;cin>>l>>r; 56 l=lower_bound(s,s+n,l)-s; 57 r=upper_bound(s,s+n,r)-s-1; 58 if(l>r) continue; 59 vl[l].push_back(r);vr[r].push_back(l); 60 } 61 ll ans=1LL*n*(n-1)*(n-2)/6; 62 for(int i=0;i<n;i++){ 63 for(int j=0;j<vl[i].size();j++) update(i,vl[i][j],0,n-1,1); 64 int res=0; 65 if(i>0) res+=i-query(0,i-1,0,n-1,1); 66 if(i<n-1) res+=query(i+1,n-1,0,n-1,1); 67 ans-=1LL*res*(res-1)/2;//乘法原理,顺序要去掉 68 for(int j=0;j<vr[i].size();j++) update(vr[i][j],i,0,n-1,1); 69 } 70 cout<<ans<<endl; 71 return 0; 72 }
不过我感觉,......