Codeforces Round #341 (Div. 2)

来源:互联网 发布:ubuntu 读取不到u盘 编辑:程序博客网 时间:2024/06/14 00:54


B. Wet Shark and Bishops
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Today, Wet Shark is given n bishops on a 1000 by 1000 grid. Both rows and columns of the grid are numbered from 1 to 1000. Rows are numbered from top to bottom, while columns are numbered from left to right.

Wet Shark thinks that two bishops attack each other if they share the same diagonal. Note, that this is the only criteria, so two bishops may attack each other (according to Wet Shark) even if there is another bishop located between them. Now Wet Shark wants to count the number of pairs of bishops that attack each other.

Input

The first line of the input contains n (1 ≤ n ≤ 200 000) — the number of bishops.

Each of next n lines contains two space separated integers xi and yi (1 ≤ xi, yi ≤ 1000) — the number of row and the number of column where i-th bishop is positioned. It's guaranteed that no two bishops share the same position.

Output

Output one integer — the number of pairs of bishops which attack each other.

Sample test(s)
input
51 11 53 35 15 5
output
6
input
31 12 33 5
output
0
Note

In the first sample following pairs of bishops attack each other: (1, 3)(1, 5)(2, 3)(2, 4)(3, 4) and (3, 5). Pairs (1, 2)(1, 4)(2, 5)and (4, 5) do not attack each other because they do not share the same diagonal.


先吐槽:Codeforces平时00:35 01:35的自己困得手都抬不起来,根本玩不了。然后好不容易碰到一个22:00的,自己玩得跟屎一样,被各种细节WA,各种着急。。。其实感觉自己心态方面也需要提升。当然当下感觉最需要提升的就是智商。太低了。。。真是受不了。。。

有1000*1000的格子,每个格子自然有两个对角线,然后给出了n个bishops的位置,然后说如果两个bishops有相同的对角线,则两个bishop会打起来。问这个n个bishops中有多少对会打起来。

一开始题意就没读懂。。。脑子犯浑了。。。发现自己读英文真是吃力。。。

画个图可以知道,发现是这样,和位置(x,y)会打起来的,是(x+step,y+step) (x-step,y+step) (x+step,y-step) (x-step,y-step) [step>=1]。然后发现这些点的坐标(x0,y0)要么是x0+y0=x+y,要么就是x0-y0=x0-y0。所以可以把等于x+y多少个记录下来,等于x-y多少个记录下来。那打起来的对数就等于个数n n*(n-1)/2。

代码:

#pragma warning(disable:4996)  #include <iostream>#include <algorithm>#include <cstring>#include <vector>#include <string>#include <cstdio>#include <cmath>#include <queue>#include <stack>#include <set>#include <map>using namespace std;#define INF 0x3ffffffftypedef long long ll;const int mod = 1e9 + 7;const int maxn = 1005;ll n;map<ll, ll>s1;map<ll, ll>s2;void solve(){ll i, x, y;scanf("%I64d", &n);for (i = 1; i <= n; i++){scanf("%I64d%I64d", &x, &y);s1[x + y]++;s2[x - y]++;}ll ans = 0;map<ll, ll>::iterator it;for (it = s1.begin(); it != s1.end(); it++){ans += it->second*(it->second - 1) / 2;}for (it = s2.begin(); it != s2.end(); it++){ans += it->second*(it->second - 1) / 2;}printf("%I64d", ans);}int main(){//freopen("i.txt","r",stdin);//freopen("o.txt","w",stdout);solve();//system("pause");return 0;}

C. Wet Shark and Flowers
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

There are n sharks who grow flowers for Wet Shark. They are all sitting around the table, such that sharks i and i + 1 are neighbours for all i from 1 to n - 1. Sharks n and 1 are neighbours too.

Each shark will grow some number of flowers si. For i-th shark value si is random integer equiprobably chosen in range from li to ri. Wet Shark has it's favourite prime number p, and he really likes it! If for any pair of neighbouring sharks i and j the product si·sj is divisible byp, then Wet Shark becomes happy and gives 1000 dollars to each of these sharks.

At the end of the day sharks sum all the money Wet Shark granted to them. Find the expectation of this value.

Input

The first line of the input contains two space-separated integers n and p (3 ≤ n ≤ 100 000, 2 ≤ p ≤ 109) — the number of sharks and Wet Shark's favourite prime number. It is guaranteed that p is prime.

The i-th of the following n lines contains information about i-th shark — two space-separated integers li and ri (1 ≤ li ≤ ri ≤ 109), the range of flowers shark i can produce. Remember that si is chosen equiprobably among all integers from li to ri, inclusive.

Output

Print a single real number — the expected number of dollars that the sharks receive in total. You answer will be considered correct if its absolute or relative error does not exceed 10 - 6.

Namely: let's assume that your answer is a, and the answer of the jury is b. The checker program will consider your answer correct, if .

Sample test(s)
input
3 21 2420 421420420 420421
output
4500.0
input
3 51 42 311 14
output
0.0
Note

A prime number is a positive integer number that is divisible only by 1 and itself. 1 is not considered to be prime.

Consider the first sample. First shark grows some number of flowers from 1 to 2, second sharks grows from 420 to 421 flowers and third from 420420 to 420421. There are eight cases for the quantities of flowers (s0, s1, s2) each shark grows:

  1. (1, 420, 420420): note that s0·s1 = 420s1·s2 = 176576400, and s2·s0 = 420420. For each pair, 1000 dollars will be awarded to each shark. Therefore, each shark will be awarded 2000 dollars, for a total of 6000 dollars.
  2. (1, 420, 420421): now, the product s2·s0 is not divisible by 2. Therefore, sharks s0 and s2 will receive 1000 dollars, while shark s1will receive 2000. The total is 4000.
  3. (1, 421, 420420): total is 4000
  4. (1, 421, 420421): total is 0.
  5. (2, 420, 420420): total is 6000.
  6. (2, 420, 420421): total is 6000.
  7. (2, 421, 420420): total is 6000.
  8. (2, 421, 420421): total is 4000.

The expected value is .

In the second sample, no combination of quantities will garner the sharks any money.


题意是n个人环形坐着,每一个人有一个区间,然后每个人随机地从区间里面选一个数,如果相邻的两个人选择的数其乘积能够被给定的p整除,那么相邻的两个人就能够得到2000刀。求所有人得到的钱的期望。

#吐槽:其实这题很简单啊。。。当时看怎么就能没有思路呢。。。

对于每一个区间来说,能够抽到p整除的概率是已知的。就是这里面有多少能够整除p的数除以总区间。然后同理嘛,两个数乘积能够整除p肯定其中一个整除p就可以了啊,然后其概率乘以2000就是期望啊。

我天我真是不想吐槽我的智商额。。。

代码:

#pragma warning(disable:4996)  #include <iostream>#include <algorithm>#include <cstring>#include <vector>#include <string>#include <cstdio>#include <cmath>#include <queue>#include <stack>#include <set>#include <map>using namespace std;#define INF 0x3ffffffftypedef long long ll;const int mod = 1e9 + 7;const int maxn = 100005;ll n, p;ll le[maxn], ri[maxn];double ans[maxn];void solve(){int i;scanf("%I64d%I64d", &n, &p);for (i = 0; i < n; i++){scanf("%d%d", &le[i], &ri[i]);ans[i] = double(ri[i] / p - (le[i] - 1) / p) / (double)(ri[i] - le[i] + 1);}double res = 0;for (i = 0; i < n - 1; i++){res += (1 - (1 - ans[i]) *(1 - ans[i + 1])) * 2000.0;}res += (1 - (1 - ans[0]) *(1 - ans[n - 1])) * 2000.0;printf("%lf", res);}int main(){//freopen("i.txt","r",stdin);//freopen("o.txt","w",stdout);solve();//system("pause");return 0;}

D. Rat Kwesh and Cheese
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Wet Shark asked Rat Kwesh to generate three positive real numbers xy and z, from 0.1 to 200.0, inclusive. Wet Krash wants to impress Wet Shark, so all generated numbers will have exactly one digit after the decimal point.

Wet Shark knows Rat Kwesh will want a lot of cheese. So he will give the Rat an opportunity to earn a lot of cheese. He will hand the three numbers xy and z to Rat Kwesh, and Rat Kwesh will pick one of the these twelve options:

  1. a1 = xyz;
  2. a2 = xzy;
  3. a3 = (xy)z;
  4. a4 = (xz)y;
  5. a5 = yxz;
  6. a6 = yzx;
  7. a7 = (yx)z;
  8. a8 = (yz)x;
  9. a9 = zxy;
  10. a10 = zyx;
  11. a11 = (zx)y;
  12. a12 = (zy)x.

Let m be the maximum of all the ai, and c be the smallest index (from 1 to 12) such that ac = m. Rat's goal is to find that c, and he asks you to help him. Rat Kwesh wants to see how much cheese he gets, so he you will have to print the expression corresponding to that ac.

Input

The only line of the input contains three space-separated real numbers xy and z (0.1 ≤ x, y, z ≤ 200.0). Each of xy and z is given with exactly one digit after the decimal point.

Output

Find the maximum value of expression among xyzxzy(xy)z(xz)yyxzyzx(yx)z(yz)xzxyzyx(zx)y(zy)x and print the corresponding expression. If there are many maximums, print the one that comes first in the list.

xyz should be outputted as x^y^z (without brackets), and (xy)z should be outputted as (x^y)^z (quotes for clarity).

Sample test(s)
input
1.1 3.4 2.5
output
z^y^x
input
2.0 2.0 2.0
output
x^y^z
input
1.9 1.8 1.7
output
(x^y)^z

给出浮点数x,y,z。每个数的取值范围是0.1到200。然后问上述式子当中最大的表达式是哪一个。

#吐槽:想到取两次log。但是没想到如果都小于1,怎么办。。。

范围是在200之内的,那200^200^200肯定是没法算的数,不用想肯定是要取log的,然后取完log发现还会有200^200这样的妖魔鬼怪,那肯定还是要再取一层log的。

所以举例来说:

x^y^z要进行比较的话就是log(log(x^y^z))=log(log(x))+z*log(y)。
(x^y)^z要进行比较的话就是log(log((x^y)^z))=log(log(x))+log(y)+log(z)。

然后这里面别的地方没什么问题,唯一有问题的就在于log(log(x)),如果x<=1,那么log(log(x))没法搞,所以这时就分情况搞了。

如果x,y,z有大于1的数,那么肯定是大于1的那个数做底,这样就能保证结果一定是一个大于1的一个数,所以log(log(x))这种情况就不会存在了,因为我就要求这个x是那个大于1的那个数。

如果x,y,z均小于等于1,那将做底的那个数,取倒数,然后因为取了log,最终值取反,最后比较哪一个是最大值。好比说(1/2)^5 = 1/(2^5)。

代码:

#pragma warning(disable:4996)  #include <iostream>#include <algorithm>#include <cstring>#include <vector>#include <string>#include <cstdio>#include <cmath>#include <queue>#include <stack>#include <set>#include <map>using namespace std;#define INF 0x3ffffffftypedef long long ll;const int mod = 1e9 + 7;const int maxn = 100005;char res[12][20] = {"x^y^z","x^z^y","(x^y)^z","(x^z)^y","y^x^z","y^z^x","(y^x)^z","(y^z)^x","z^x^y","z^y^x","(z^x)^y","(z^y)^x",};double x, y, z;double val[20];void change(){x = 1 / x;val[0] = z*log(y) + log(log(x));val[1] = y*log(z) + log(log(x));val[2] = log(y) + log(z) + log(log(x));val[3] = log(y) + log(z) + log(log(x));x = 1 / x;y = 1 / y;val[4] = z*log(x) + log(log(y));val[5] = x*log(z) + log(log(y));val[6] = log(x) + log(z) + log(log(y));val[7] = log(x) + log(z) + log(log(y));y = 1 / y;z = 1 / z;val[8] = y*log(x) + log(log(z));val[9] = x*log(y) + log(log(z));val[10] = log(x) + log(y) + log(log(z));val[11] = log(x) + log(y) + log(log(z));int i;for (i = 0; i < 12; i++){val[i] = - val[i];}}void solve(){cin >> x >> y >> z;double re = -1000000;if (log(x) < 0){val[0] = -1000005;val[1] = -1000005;val[2] = -1000005;val[3] = -1000005;}else{val[0] = z*log(y) + log(log(x));val[1] = y*log(z) + log(log(x));val[2] = log(y) + log(z) + log(log(x));val[3] = log(y) + log(z) + log(log(x));}if (log(y) < 0){val[4] = -1000005;val[5] = -1000005;val[6] = -1000005;val[7] = -1000005;}else{val[4] = z*log(x) + log(log(y));val[5] = x*log(z) + log(log(y));val[6] = log(x) + log(z) + log(log(y));val[7] = log(x) + log(z) + log(log(y));}if (log(z) < 0){val[8] = -1000005;val[9] = -1000005;val[10] = -1000005;val[11] = -1000005;}else{val[8] = y*log(x) + log(log(z));val[9] = x*log(y) + log(log(z));val[10] = log(x) + log(y) + log(log(z));val[11] = log(x) + log(y) + log(log(z));}int i, flag = 0;if (x <= 1 && y <= 1 && z <= 1){change();}for (i = 0; i < 12; i++){if (val[i] > re){flag = i;re = val[i];}}cout << res[flag];}int main(){//freopen("i.txt","r",stdin);//freopen("o.txt","w",stdout);solve();//system("pause");return 0;}

E. Wet Shark and Blocks
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

There are b blocks of digits. Each one consisting of the same n digits, which are given to you in the input. Wet Shark must chooseexactly one digit from each block and concatenate all of those digits together to form one large integer. For example, if he chooses digit1 from the first block and digit 2 from the second block, he gets the integer 12.

Wet Shark then takes this number modulo x. Please, tell him how many ways he can choose one digit from each block so that he gets exactly k as the final result. As this number may be too large, print it modulo 109 + 7.

Note, that the number of ways to choose some digit in the block is equal to the number of it's occurrences. For example, there are 3 ways to choose digit 5 from block 3 5 6 7 8 9 5 1 1 1 1 5.

Input

The first line of the input contains four space-separated integers, nbk and x (2 ≤ n ≤ 50 000, 1 ≤ b ≤ 109, 0 ≤ k < x ≤ 100, x ≥ 2) — the number of digits in one block, the number of blocks, interesting remainder modulo x and modulo x itself.

The next line contains n space separated integers ai (1 ≤ ai ≤ 9), that give the digits contained in each block.

Output

Print the number of ways to pick exactly one digit from each blocks, such that the resulting integer equals k modulo x.

Sample test(s)
input
12 1 5 103 5 6 7 8 9 5 1 1 1 1 5
output
3
input
3 2 1 26 2 2
output
0
input
3 2 1 23 1 2
output
6
Note

In the second sample possible integers are 222662 and 66. None of them gives the remainder 1 modulo 2.

In the third sample integers 1113212331 and 33 have remainder 1 modulo 2. There is exactly one way to obtain each of these integers, so the total answer is 6.


E题题意是给出b个块,每个块里面有相同的n个数字,然后从b个块里面分别取一个数字组成一个大的数字,问这个数字模给定的x结果是k的个数有多少。

首先的思路肯定是递推 dp[x][y]表示前x块余数为y的个数,那就有dp[i][(j*10+k)%x]=dp[i-1][j]*cnt[k]。这样做有一个问题,这样滚动数组推你要推b次(10^9数量级),每一次你还要遍历每一个块里面的cnt[k],这样做是肯定TLE的。另外发现每一次递推其模式是一样的,所以要想到矩阵的快速幂。

dp[i][j]表示上一次余数是i这一次余数是j的个数,那转换一次的话,起始地这个矩阵值是使其从i到j的每一块中那个数值的个数。

然后取了b次,这个矩阵就乘以b次,快速幂搞。

代码:

#pragma warning(disable:4996)  #include <iostream>#include <algorithm>#include <cstring>#include <vector>#include <string>#include <cstdio>#include <cmath>#include <queue>#include <stack>#include <set>#include <map>using namespace std;#define INF 0x3ffffffftypedef long long ll;const ll mod = 1e9 + 7;const int maxn = 105;int n, b, k, x;ll ans[maxn][maxn], tmp[maxn][maxn];void mul(ll a[maxn][maxn], ll b[maxn][maxn]){int i, j, k;int res[maxn][maxn];memset(res, 0, sizeof(res));for (i = 0; i <= x - 1; i++){for (j = 0; j <= x - 1; j++){for (k = 0; k <= x - 1; k++){res[i][j] += (a[i][k] * b[k][j]) % mod;res[i][j] = res[i][j] % mod;}}}for (i = 0; i <= x - 1; i++){for (j = 0; j <= x - 1; j++){a[i][j] = res[i][j];}}}void solve(){int i, j, tp;scanf("%d%d%d%d", &n, &b, &k, &x);memset(ans, 0, sizeof(ans));for (i = 1; i <= n; i++){scanf("%d", &tp);for (j = 0; j <= x - 1; j++){ans[j][(j * 10 + tp) % x]++;}}for (i = 0; i <= x - 1; i++){tmp[i][i] = 1;}while (b){if (b & 1){mul(tmp, ans);}mul(ans, ans);b = b >> 1;}printf("%I64d", tmp[0][k]);}int main(){//freopen("i.txt","r",stdin);//freopen("o.txt","w",stdout);solve();//system("pause");return 0;}

0 0
原创粉丝点击