# Codeforces Round #369 (Div. 2)解题报告

A. Bus to Udayland
1、题意：找个OO改成++。题面
2、分析：mdzz…..

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
#define M 1000010

char ch = getchar(); int x = 0, f = 1;
while(ch < '0' || ch > '9'){
if(ch == '-') f = -1;
ch = getchar();
}
while('0' <= ch && ch <= '9'){
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}

char ch[1010][10];

int main(){
for(int i = 1; i <= n; i ++) scanf("%s", ch[i]);
for(int i = 1; i <= n; i ++){
if(ch[i][0] == 'O' && ch[i][1] == 'O'){
puts("YES");
for(int j = 1; j <= n; j ++){
if(j != i) printf("%s\n", ch[j]);
else printf("++%c%c%c\n", ch[j][2], ch[j][3], ch[j][4]);
}
return 0;
}
if(ch[i][3] == 'O' && ch[i][4] == 'O'){
puts("YES");
for(int j = 1; j <= n; j ++){
if(j != i) printf("%s\n", ch[j]);
else printf("%c%c%c++\n", ch[j][0], ch[j][1], ch[j][2]);
}
return 0;
}
}
puts("NO");
return 0;
}

B. Chris and Magic Square 题面
1、题意：在一个矩阵中让你填一个数，填完之后满足所有的行，所有的列以及两条对角线的和相等。
2、分析：我们首先随便找一个没有这个数的行，算出sum，然后此位置的一行相减，求出这个数，然后判断一下和是否相等就行。注意n=1$n=1$

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
#define M 510
#define LL long long

char ch = getchar(); LL x = 0, f = 1;
while(ch < '0' || ch > '9'){
if(ch == '-') f = -1;
ch = getchar();
}
while('0' <= ch && ch <= '9'){
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}

LL a[M][M];

int main(){
LL n = read(); LL x, y;
for(LL i = 1; i <= n; i ++){
for(LL j = 1; j <= n; j ++){
if(a[i][j] == 0) x = i, y = j;
}
}
if(n == 1){
puts("1");
return 0;
}
LL t = 1;
if(x == t){
t ++;
}
LL sum = 0, tsum = 0;
for(LL i = 1; i <= n; i ++) sum += a[t][i];
for(LL i = 1; i <= n; i ++) if(i != y) tsum += a[x][i];
LL ans = sum - tsum; tsum = sum;
a[x][y] = ans;
for(LL i = 1; i <= n; i ++){
sum = 0;
for(LL j = 1; j <= n; j ++) sum += a[i][j];
if(sum != tsum){
return puts("-1"), 0;
}
}
for(LL i = 1; i <= n; i ++){
sum = 0;
for(LL j = 1; j <= n; j ++) sum += a[j][i];
if(sum != tsum){
return puts("-1"), 0;
}
}
sum = 0;
for(LL i = 1; i <= n; i ++){
sum += a[i][i];
}
if(sum != tsum) return puts("-1"), 0;
sum = 0;
for(LL i = 1; i <= n; i ++){
sum += a[n - i + 1][i];
}
if(sum != tsum) return puts("-1"), 0;
if(ans < 1) return puts("-1"), 0;
printf("%I64d\n", ans);
return 0;
}

C. Coloring Trees 题面
1、题意：给一排树，有些树有颜色，有些没有，你需要给没有颜色的树染上颜色，第i棵树染成j颜色需要用pi,j$p_{i,j}$块钱，将这一排数染成w段颜色需要最少用多少块钱。
2、分析：一眼题，随手写一发dp咯，f[i][j][k]$f[i][j][k]$表示第i棵树、这个树是j颜色，已经有k段了，转移随便yy一下就好了

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
#define M 110
#define LL long long

char ch = getchar(); int x = 0, f = 1;
while(ch < '0' || ch > '9'){
if(ch == '-') f = -1;
ch = getchar();
}
while('0' <= ch && ch <= '9'){
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}

LL f[M][M][M];
int col[M];
LL p[M][M];

int main(){
for(int i = 1; i <= n; i ++) col[i] = read();
for(int i = 1; i <= n; i ++){
for(int j = 1; j <= m; j ++){
scanf("%I64d", &p[i][j]);
}
}
memset(f, 0x3f, sizeof(f));
f[0][0][0] = 0;
for(int i = 0; i < n; i ++){
for(int j = 0; j <= k; j ++){
for(int k = 0; k <= m; k ++){
if(f[i][j][k] == 0x3f3f3f3f3f3f3f3fll) continue;
if(col[i + 1]){
f[i + 1][j + (k != col[i + 1])][col[i + 1]] = min(f[i][j][k], f[i + 1][j + (k != col[i + 1])][col[i + 1]]);
}
else{
for(int w = 1; w <= m; w ++){
f[i + 1][j + (k != w)][w] = min(f[i][j][k] + p[i + 1][w], f[i + 1][j + (k != w)][w]);
}
}
}
}
}
LL ans = 0x3f3f3f3f3f3f3f3fll;
for(int i = 0; i <= m; i ++) ans = min(ans, f[n][k][i]);
if(ans == 0x3f3f3f3f3f3f3f3fll) ans = -1;
printf("%I64d\n", ans);
return 0;
}

1、题意：n个点n条边的有向图，你可以改变有向边的方向，问改成没有环的方案数。
2、分析：一眼题。。很显然，每一个联通分量里面只会有一个简单环= =|||，在每个联通分量里面，这个简单环不能变成环的方案数明显是2size2$2^{size}-2$，环外的边就无所谓咯。拿个并查集维护一下就好了，最后所有联通分量的乘积就是答案。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
#define M 400010
#define LL long long
#define MOD 1000000007ll

char ch = getchar(); LL x = 0, f = 1;
while(ch < '0' || ch > '9'){
if(ch == '-') f = -1;
ch = getchar();
}
while('0' <= ch && ch <= '9'){
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}

struct Node{
LL x, y;
} a[M];

struct Edge{
LL u, v, next;
} G[M];

LL fa[M], sz[M], fk[M];

inline LL find(LL x){
return fa[x] == x ? x : fa[x] = find(fa[x]);
}

LL res;

inline void dfs(LL x, LL t, LL y, LL ff){
if(x == y){
res = t;
return;
}
for(LL i = head[x]; i != -1; i = G[i].next) if(G[i].v != ff){
dfs(G[i].v, t + 1, y, x);
if(res) return;
}
}

inline void add(LL x, LL y){
G[++ tot] = (Edge){x, y, head[x]};
G[++ tot] = (Edge){y, x, head[y]};
}

LL pow[M];

int main(){
for(LL i = 1; i <= n; i ++){
a[i] = (Node){i, x};
}
pow[0] = 1;
for(LL i = 1; i <= n; i ++) pow[i] = pow[i - 1] * 2 % MOD;
for(LL i = 1; i <= n; i ++) fa[i] = i, sz[i] = 1;
LL ans = 1;
for(LL i = 1; i <= n; i ++){
LL x = a[i].x, y = a[i].y;
LL p = find(x), q = find(y);
if(p == q){
res = 0;
dfs(x, 1, y, 0);
ans *= pow[sz[p] - res];
ans %= MOD;
ans *= (pow[res] + MOD - 2);
ans %= MOD;
fk[p] = 1;
}
else fa[p] = q, add(x, y), sz[q] += sz[p], fk[q] |= fk[p], ans = ans * (fk[p] ? pow[sz[q] - sz[p]] : (fk[q] ? pow[sz[p]] : 1ll)) % MOD;
}
printf("%I64d\n", ans);
return 0;
}

E. ZS and The Birthday Paradox
1、题意：让你求2nk(2n+2n1+...+2nk+1)2nk$\frac{{2^n}^k-(2^n+2^n-1+...+2^n-k+1)}{{2^n}^k}$
2、分析：额，你想问为啥是求那个式子么，自行百度生日悖论，然后就是这个式子了。。这个式子怎么做，观察此题的特点，我们发现MOD非常小，才106+3$10^6+3$，从MOD入手，当k≥MOD时，分子是0。。否则就暴力算出分子，分母还用说么。怎么约分呢？我们可以这样，观察分母，我们发现分母只有一个质因子，那就是2！于是我们logk$logk$的时间算出分子中有多少个2就行了。。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
#define M 1000010
#define MOD 1000003
#define LL long long
#define ULL unsigned long long

char ch = getchar(); LL x = 0, f = 1;
while(ch < '0' || ch > '9'){
if(ch == '-') f = -1;
ch = getchar();
}
while('0' <= ch && ch <= '9'){
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}

inline LL pow(LL x, LL y){
while(y < 0) y += MOD;
LL ret = 1;
while(y){
if(y & 1) (ret *= x) %= MOD;
(x *= x) %= MOD;
y >>= 1;
}
return ret;
}

int main(){
LL n, k;
if(n < 63){
if(k > (1ll << n)){
return puts("1 1"), 0;
}
}
LL up, down;
if(k >= MOD) up = 0;
else{
up = 1;
for(LL i = 1; i < k; i ++){
up = (up * (pow(2ll, n) - i)) % MOD;
}
}
//printf("%lld\n", up);
down = pow(pow(2ll, n), k - 1);
for(ULL i = 2; i < k; i <<= 1){
LL t = pow(pow(2ll, (k - 1) / i), MOD - 2);
up = (up * t) % MOD;
down = (down * t) % MOD;
}
up = (down - up + MOD) % MOD;
printf("%I64d %I64d\n", up, down);
return 0;
}

## codeforces Round #264(div2) B解题报告

B. Caisa and Pylons time limit per test 1 second memory limit per test 256 megabytes ...

## Codeforces Round #401 (div. 2)解题报告

Problem A-Shell Game 找规律 6个一组 //Author: Lixiang #include struct Shell_Game{ int N,X; void init()...

## codeforces Round #238(div2) B解题报告

B. Domino Effect time limit per test 1 second memory limit per test 256 megabytes i...

## codeforces round 200 div2解题报告

A. Magnets time limit per test 1 second memory limit per test 256 megabytes input ...

A. Initial Bet

## codeforces Round #261(div2) A解题报告

A. Pashmak and Garden time limit per test 1 second memory limit per test 256 megabytes ...

## Codeforces Round #241 (Div. 2) 解题报告

Codeforces Round #241 (Div. 2) A. Guess a number! time limit per test 1 secon...
• kbdwo
• 2014-04-17 14:07
• 721

## Codeforces Round #291 (Div. 2) 解题报告 (A B C D)

A Chewbaсca and Number         贪心，每一位取t和9-t中较小的。注意首位不能为0。 #include #include #include #incl...

举报原因： 您举报文章：深度学习：神经网络中的前向传播和反向传播算法推导 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)