[TS-A1487][2013中国国家集训队第二次作业]分配游戏[二分]
根据题意,设$3n$次比较中胜了$w$次,负了$l$次,平了$d$次,所有场次中胜了$W$次,负了$L$次,平了$D$次。如果一场赢了,那么$w-l$就会$+1$,相同地,$W-L$也会$+1$;如果输了一场$w-l$就会$-1$,$W-L$也会$-1$。另外,再一局中如果有一次比较平了,那么这一场就一定是平局。所以对于每次查询,二分统计分别共计胜负平的比较次数,则可知$W-L=w-l$,所以$\frac{((W+L+D)+(W-l)-D)}{2}即为答案,最后就是$D$的计算方法。$D$的大小在没有三次比较完全一样的时候等于$d$,所以只需要减去三次都一样的 次数$*2$ 即可。
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 int n,m,N,cnt; 6 int a[110000],b[110000],c[110000]; 7 8 pair<pair<int,int>,int>vec[110000]; 9 10 int getint() 11 { 12 int data=0; 13 char ch=getchar(); 14 while(ch<'0' || ch>'9')ch=getchar(); 15 while(ch>='0' && ch<='9')data=data*10+ch-48,ch=getchar(); 16 return data; 17 } 18 19 template<class _tp> 20 _tp* lower_bound(_tp*l,_tp*r,const _tp val) 21 { 22 _tp*mid; 23 while(l!=r) 24 { 25 mid=l+((r-l)>>1); 26 if(*mid<val)l=mid+1; 27 else r=mid; 28 } 29 return r; 30 } 31 32 template<class _tp> 33 _tp* upper_bound(_tp*l,_tp*r,const _tp val) 34 { 35 _tp*mid; 36 while(l!=r) 37 { 38 mid=l+((r-l)>>1); 39 if(*mid<=val)l=mid+1; 40 else r=mid; 41 } 42 return r; 43 } 44 45 int main() 46 { 47 int i,*temp1,*temp2; 48 49 pair<pair<int,int>,int>t; 50 N=getint(),n=getint(),m=getint(); 51 52 for(i=1;i<=n;++i) 53 { 54 a[i]=getint(),b[i]=getint(),c[i]=getint(); 55 vec[++cnt]=make_pair(make_pair(a[i],b[i]),c[i]); 56 } 57 58 sort(a+1,a+n+1); 59 sort(b+1,b+n+1); 60 sort(c+1,c+n+1); 61 sort(vec+1,vec+n+1); 62 63 for(i=1;i<=m;++i) 64 { 65 int x,y,z,W,D,L; 66 67 x=getint(),y=getint(),z=getint(); 68 W=0,L=0,D=0; 69 70 W+=(temp1=lower_bound(a+1,a+n+1,x))-a-1; 71 L+=(a+n+1)-(temp2=upper_bound(a+1,a+n+1,x)); 72 D+=temp2-temp1; 73 W+=(temp1=lower_bound(b+1,b+n+1,y))-b-1; 74 L+=(b+n+1)-(temp2=upper_bound(b+1,b+n+1,y)); 75 D+=temp2-temp1; 76 W+=(temp1=lower_bound(c+1,c+n+1,z))-c-1; 77 L+=(c+n+1)-(temp2=upper_bound(c+1,c+n+1,z)); 78 D+=temp2-temp1; 79 t=make_pair(make_pair(x,y),z); 80 D-=(upper_bound(vec+1,vec+n+1,t)-lower_bound(vec+1,vec+n+1,t))<<1; 81 82 printf("%d\n",(n+(W-L)-D)>>1); 83 } 84 85 return 0; 86 }