首页 > 代码库 > 【权值分块】bzoj3570 DZY Loves Physics I
【权值分块】bzoj3570 DZY Loves Physics I
以下部分来自:http://www.cnblogs.com/zhuohan123/p/3726306.html
DZY系列。
这题首先是几个性质:
1.所有球质量相同,碰撞直接交换速度,而球又没有编号,那么就可以直接视作两个球没有碰撞。
2.所有的方向、初始位置都没有任何用处。
然后就是速度的问题了,根据题设
a⋅v=C
与这几个方程联立
a⋅v=C
s=v·t;
vt2=v02+2·a·s
解这个方程组,可以得到
vt=√(2·C·t+v02)
那么T时刻的速度vT的相对大小就直接由v0决定了,我们只需要找到第k小的v0,直接输出答案即可。
现在问题在于:支持插入,查询全局K大值。
平衡树显然可做,但是 权值线段树/权值树状数组 不是更快吗?
但是 权值分块 竟然更快呢?
可能是因为其极小的常数 以及 插入时O(1) 的复杂度吧。
1 #include<cstdio> 2 #include<cmath> 3 using namespace std; 4 #define max(a,b) (((a)>(b))?(a):(b)) 5 int n,K,V,v[100001],m,b[100001],LIMIT,sz,sum,sumv[350],l[350],r[350],num[100001]; 6 bool op; 7 double CONST,T; 8 inline int R(){ 9 char c=0;int f=1,x;10 for(;c<‘0‘||c>‘9‘;c=getchar())if(c==‘-‘)f=-1;11 for(x=0;c>=‘0‘&&c<=‘9‘;c=getchar())(x*=10)+=(c-‘0‘);12 x*=f; return x;13 }14 void makeblock()15 {16 sz=sqrt(LIMIT); if(!sz) sz=1; r[0]=-1;17 for(sum=1;sum*sz<LIMIT;sum++)18 {19 l[sum]=r[sum-1]+1;20 r[sum]=sum*sz;21 for(int i=l[sum];i<=r[sum];i++) num[i]=sum;22 }23 l[sum]=r[sum-1]+1;24 r[sum]=LIMIT;25 for(int i=l[sum];i<=r[sum];i++) num[i]=sum;26 }27 void Insert(const int &x){b[x]++; sumv[num[x]]++;}28 inline int Kth(const int &x)29 {30 int cnt=0;31 for(int i=1;;i++)32 {33 cnt+=sumv[i];34 if(cnt>=x)35 {36 cnt-=sumv[i];37 for(int j=l[i];;j++)38 {cnt+=b[j]; if(cnt>=x) return j;}39 }40 }41 }42 inline double sqr(const double &x){return x*x;}43 int main()44 {45 n=R(); CONST=(double)R();46 for(int i=1;i<=n;i++)47 {48 v[i]=R(); R(); R();49 LIMIT=max(LIMIT,v[i]);50 } makeblock(); m=R();51 for(int i=1;i<=n;i++) Insert(v[i]);52 for(int i=1;i<=m;i++)53 {54 op=R(); if(op)55 {56 T=(double)R(); K=R();57 printf("%.3f\n",sqrt(2.0*CONST*T+sqr((double)Kth(K))));58 }59 else {V=R(); R(); R(); Insert(V);}60 }61 return 0;62 }
【权值分块】bzoj3570 DZY Loves Physics I
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。