BZOJ3570: DZY Loves Physics I
DZY系列。
这题首先是几个性质:
1.所有球质量相同,碰撞直接交换速度,而球又没有编号,那么就可以直接视作两个球没有碰撞。
2.所有的方向、初始位置都没有任何用处。
然后就是速度的问题了,根据题设\[v'\cdot v = C\]解这个方程,可以得到\[v=\sqrt{2ct+v_0^2}\]
那么\(T\)时可的速度\(v_T\)的相对大小就直接由\(v_0\)决定了,我们只需要找到第\(k\)小的\(v_0\),直接输出答案即可。
最后一个问题是怎么找第\(k\)小的\(v_0\),这里用了一个树状数组的奇怪性质:可以在\(O(\lg n)\)的时间内完成二分第\(k\)小这件事,具体可以看代码+对着树状数组的图理解。
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <cstring> 5 #include <algorithm> 6 using namespace std; 7 typedef long long LL; 8 inline int getnum() 9 { 10 int ans=0,fh=1;char ch=getchar(); 11 while(ch<'0'||ch>'9'){if(ch=='-')fh*=-1;ch=getchar();} 12 while(ch>='0'&&ch<='9')ans=ans*10+ch-'0',ch=getchar(); 13 return fh*ans; 14 } 15 int n,C; 16 const int tsize=1<<17; 17 int t[210000]; 18 inline void insert(int x){for(;x<=tsize;x+=x&(-x))t[x]++;} 19 int main(int argc, char *argv[]) 20 { 21 n=getnum(),C=getnum(); 22 while(n--)insert(getnum()),getnum(),getnum(); 23 int q=getnum(); 24 while(q--) 25 { 26 if(getnum()) 27 { 28 int T=getnum(),kth=getnum(); 29 int l=0,r=tsize,tsum=0,ans; 30 while(l<r) 31 { 32 int mid=(l+r)/2;tsum+=t[mid]; 33 if(tsum>=kth)r=mid,ans=mid,tsum-=t[mid]; 34 else l=mid+1; 35 } 36 printf("%.3lf\n",sqrt((LL)2*C*T+(LL)l*l)); 37 } 38 else insert(getnum()),getnum(),getnum(); 39 } 40 return 0; 41 }