NowCoder Contest 894
牛客练习赛46。比cf div2稍难一些。题目区分度倒是很高。
题目链接:https://ac.nowcoder.com/acm/contest/894#question
A:
一看就知道两个小半圆半径相等时满足题意。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 #define ll long long 3 #define pb push_back 4 #define mp make_pair 5 #define sot(a,b) sort(a+1,a+1+b) 6 #define rep(i,a,b) for (int i=a;i<=b;i++) 7 #define eps 1e-8 8 #define int_inf (1<<30)-1 9 #define ll_inf (1LL<<62)-1 10 #define lson curPos<<1 11 #define rson curPos<<1|1 12 13 using namespace std; 14 15 double a; 16 const double pi = acos(-1.0); 17 18 int main() 19 { 20 scanf("%lf", &a); 21 printf("%.3f\n", 2.0 * sqrt(a / pi)); 22 return 0; 23 }
B:
设sum_a为a的前缀和,sum_b为b的前缀和。则以(x1,y1)为左上角,以(x2,y2)为右下角的矩阵的权值为(sum_a[x2]-sum_a[x1-1])*(sum_b[y2]-sum_b[y1-1]),其中要满足x1<=x2,y1<=y2。x1,x2的选择与y1,y2的选择相互独立。可以预处理所有y1,y2的组合,然后排序。接下来枚举x1,x2,对y二分即可。时间复杂度O(n^2*log(m^2))
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 #define ll long long 3 #define pb push_back 4 #define mp make_pair 5 #define sot(a,b) sort(a+1,a+1+b) 6 #define rep(i,a,b) for (int i=a;i<=b;i++) 7 #define eps 1e-8 8 #define int_inf (1<<30)-1 9 #define ll_inf (1LL<<62)-1 10 #define lson curPos<<1 11 #define rson curPos<<1|1 12 13 using namespace std; 14 15 const int maxn = 1e3 + 10; 16 int n, m; 17 ll l, r, a[maxn], b[maxn], c[maxn * maxn], ans = 0; //a b是a b数组前缀和 18 19 int main() 20 { 21 scanf("%d%d%lld%lld", &n, &m, &l, &r); 22 for (int i = 1; i <= n; i++) 23 { 24 ll x; scanf("%lld", &x); 25 a[i] = a[i - 1] + x; 26 } 27 for (int i = 1; i <= m; i++) 28 { 29 ll x; scanf("%lld", &x); 30 b[i] = b[i - 1] + x; 31 } 32 int cnt = 0; 33 for (int i = 0; i < m; i++) //不同区间的b数组之和 34 { 35 for (int j = i + 1; j <= m; j++) 36 c[++cnt] = b[j] - b[i]; 37 } 38 sort(c + 1, c + 1 + cnt); 39 for (int i = 0; i < n; i++) 40 for (int j = i + 1; j <= n; j++) //枚举a数组区间 41 { 42 ll x = a[j] - a[i], u = (l - 1) / x + 1, v = r / x; 43 ll lab1 = lower_bound(c + 1, c + 1 + cnt, u) - c; 44 ll lab2 = upper_bound(c + 1, c + 1 + cnt, v) - c; 45 ans += lab2 - lab1; 46 } 47 printf("%lld\n", ans); 48 return 0; 49 }
C:
推起来有点麻烦的一道概率题。不妨设a[i]为进行了i轮游戏黑球个数的期望,显然a[0]=n。a[i+1]=
化简得a[i+1]=(a[i]+p)*(n+m)/(n+m+1),可用矩阵快速幂求解。也可以接着推下去:
a[0]=n
a[1]=s*n+p*s=n*s+p*s
a[2]=s*a[1]+p*s=n*s^2+p*s^2+p*s
a[3]=s*a[2]+p*s=n*s^3+p*s^3+p*s^2+p*s
不难得出a[k]=n*s^k+p*(s^1+s^2+...+s^k)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* basic header */ 2 #include <bits/stdc++.h> 3 /* define */ 4 #define ll long long 5 #define dou double 6 #define pb emplace_back 7 #define mp make_pair 8 #define sot(a,b) sort(a+1,a+1+b) 9 #define rep1(i,a,b) for(int i=a;i<=b;++i) 10 #define rep0(i,a,b) for(int i=a;i<b;++i) 11 #define eps 1e-8 12 #define int_inf 0x3f3f3f3f 13 #define ll_inf 0x7f7f7f7f7f7f7f7f 14 #define lson curPos<<1 15 #define rson curPos<<1|1 16 /* namespace */ 17 using namespace std; 18 /* header end */ 19 20 const int mod = 1e9 + 7; 21 int n, m, k, a, b; 22 23 ll qp(ll a, ll b) 24 { 25 ll ret = 1; 26 while (b) 27 { 28 if (b & 1) ret = ret * a % mod; 29 a = a * a % mod; 30 b >>= 1; 31 } 32 return ret; 33 } 34 35 int main() 36 { 37 scanf("%d%d%d%d%d", &n, &m, &k, &a, &b); 38 int p = ((ll)a * qp(b, mod - 2)) % mod, s = (qp(n + m + 1, mod - 2) * ((ll)n + m)) % mod; 39 int ans = ((ll)n * qp(s, k) % mod + (ll)p * s % mod * (1 - qp(s, k) + mod) % mod * qp(1 - s, mod - 2) % mod) % mod; 40 printf("%d\n", (ans+mod)%mod); 41 return 0; 42 }
D:
看题都有点费劲……
二分时间。后面贪心的选择攻击策略。对于二分出来的时间t,因为a是循环数组,对于每个i,1<=i<=n,可以算出最大的整数d,使得i+d*n<=t,实际上可以看作a[i]*b[j]可以使用d次。可以把所有的a[i]*b[1]存在一个优先队列,每次取最小,次数用光后在放入a[i]*b[2],直到C或W小于等于0。
E:
由物理知识我们知道,若某一时刻a球比b球速度快,则a球始终比b球速度快。对于1操作 v1,t1,m1。可以算出V1=v1+g*(T-t1)。对于2操作,可以算出V2=v2+g*(T-t2)。则需要查询的小球即是满足V1<=V2的小球。然后根据公式m1*(v1+g*(t2-t1))^2,拆开,维护三个树状数组即可。
这题如果线段树姿势不对有可能会TLE。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* basic header */ 2 #include <bits/stdc++.h> 3 /* define */ 4 #define ll long long 5 #define dou double 6 #define pb emplace_back 7 #define mp make_pair 8 #define sot(a,b) sort(a+1,a+1+b) 9 #define rep1(i,a,b) for(int i=a;i<=b;++i) 10 #define rep0(i,a,b) for(int i=a;i<b;++i) 11 #define eps 1e-8 12 #define int_inf 0x3f3f3f3f 13 #define ll_inf 0x7f7f7f7f7f7f7f7f 14 #define lson curPos<<1 15 #define rson curPos<<1|1 16 /* namespace */ 17 using namespace std; 18 /* header end */ 19 20 const int maxn = 5e6 + 10; 21 const int mod = 1e9 + 7; 22 23 struct Node 24 { 25 ll mv_2, _2mvg, mg_2; 26 Node() 27 { 28 mv_2 = _2mvg = mg_2 = 0; 29 } 30 } bit[maxn]; 31 int q, op; 32 ll v, m, t; 33 34 void add(ll pos, ll a, ll b, ll c) 35 { 36 while (pos < maxn) 37 { 38 bit[pos].mv_2 += a; 39 bit[pos]._2mvg += b; 40 bit[pos].mg_2 += c; 41 pos += pos & -pos; 42 } 43 } 44 45 Node sum(ll pos) 46 { 47 Node ret = Node(); 48 while (pos) 49 { 50 ret.mv_2 = (ret.mv_2 + bit[pos].mv_2) % mod; 51 ret._2mvg = (ret._2mvg + bit[pos]._2mvg) % mod; 52 ret.mg_2 = (ret.mg_2 + bit[pos].mg_2) % mod; 53 pos -= pos & -pos; 54 } 55 return ret; 56 } 57 58 int main() 59 { 60 scanf("%d", &q); 61 while (q--) 62 { 63 scanf("%d", &op); 64 if (op == 1) 65 { 66 scanf("%lld%lld%lld", &v, &t, &m); 67 v = v - 10 * t; 68 add(v + 2e6, (m * v * v) % mod, (2LL * m * v * 10 % mod + mod) % mod, m * 100 % mod); 69 } 70 else 71 { 72 scanf("%lld%lld", &v, &t); 73 v = v - 10 * t + 2e6; 74 Node ans = sum(v); 75 ll sum = ans.mv_2 % mod; 76 sum = (sum + ans._2mvg % mod * t % mod) % mod; 77 sum = (sum + ans.mg_2 % mod * t % mod * t % mod) % mod; 78 printf("%lld\n", (sum + mod) % mod); 79 } 80 } 81 return 0; 82 }
F:
有点神仙的题,以后再说吧(咕咕咕