博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
福建省队集训被虐记——DAY3
阅读量:5135 次
发布时间:2019-06-13

本文共 5659 字,大约阅读时间需要 18 分钟。

昨天没写……今天补上吧

一如既往的跪了

棋盘

【问题描述】

给出一个N*M的方格棋盘,每个格子里有一盏灯和一个开关,开始的时候,所有的灯都是关着的。用(x, y)表示第x行,y列的格子。(x, y)的开关可以改变(x, y)中灯的状态,同时也可以改变满足|x’-x|=2,|y’-y|=1或者|x’-x|=1,|y’-y|=2的格子(x’, y’)的状态。改变状态的意思是,原来开着的灯会被关掉,原来关着的灯会被开起来。注意这边的改变状态是强制改变的。每个格子的开关最多只能按一次,求能使得所有灯都打开的方案数mod123456789的值。

【输入格式】

第一行,N,M。

【输出格式】

输出一个整数,表示答案。

【样例输入1】

2 3

【样例输出1】

4

【样例解释1】

XX.    .X.    XXX   .XX

XX.    XXX    .X.   .XX

其中X代表按这个格子的开关。

【样例输入2】

3 3

【样例输出2】

1

【样例解释2】

全取。

【数据规模与约定】

对于30%的数据,N*M<=20。

对于60%的数据,N*M<=200。

对于100%的数据,N,M<=150。

30分是暴力……不用讲

60分是高斯消元……因为最多只有n*m=150个点,高斯消元150^3可以过

100分是坑一点的加优化的高斯消元……在原来的基础上加个bitset还是什么的优化再乱搞+常数优化的就A了

题解上是这样描述正解的:

对于100%的数据,我们考虑缩减变量规模和方程规模。

假如我们确定了前2行和第一列的情况:

******

******

*x....

*.....

我们注意到,x格子的取法唯一。因为我们要满足最左上方那个格子。

同理,其他的格子的取法也可以如此推出来了。

现在我们的变量个数变成了N+M级别的。

那么同理,我们注意到,如果不是倒2行或者倒1列的格子,一定可以被满足。

所以我们只需要对这边的格子列方程即可。

现在变量数和方程数都是N+M级别的。高斯消元即可。

让我这连高斯消元都不会的情何以堪

// TopCoder Member SRM 494 Div 1 KnightsOut#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;const int Q = 123456789;const int u[9][2] = { {1, 2}, {1, -2}, {2, 1}, {2, -1}, {-1, 2}, {-1, -2}, {-2, 1}, {-2, -1}, {0, 0}};int N, M;int calculatePower(int p) { int res = 1, i; for (i = 0; i < p; i ++) res = (res * 2) % Q; return res; }int main() { freopen("chess.in", "r", stdin); freopen("chess.out", "w", stdout); scanf("%d%d", &N, &M); if (N == 1 || M == 1) { puts("1"); return 0; } int i, j, k, d, t1, t2, cnt, tot = 0, loc; vector< vector< vector
> > eqn(N); for (i = 0; i < N; i ++) { eqn[i].resize(M); for (j = 0; j < M; j ++) eqn[i][j].assign(2 * M + N - 1, 0); } for (i = 0; i < M; i ++) eqn[0][i][i] = eqn[1][i][M+i] = 1; for (i = 2; i < N; i ++) eqn[i][0][2*M+i-2] = 1; for (i = 2; i < N; i ++) for (j = 1; j < M; j ++) { eqn[i][j][2*M+N-2] = 1; for (d = 0; d < 9; d ++) { t1 = i - 2 + u[d][0], t2 = j - 1 + u[d][1]; if (0 <= t1 && t1 < N && 0 <= t2 && t2 < M) if (t1 != i || t2 != j) for (k = 0; k < 2 * M + N - 1; k ++) if (eqn[t1][t2][k] == 1) eqn[i][j][k] ^= 1; } } vector< vector
> mat(2 * M + N - 1); for (i = 0; i < 2 * M + N - 1; i ++) mat[i].assign(2 * M + N - 1, 0); for (i = 0; i < N; i ++) for (j = 0; j < M; j ++) if (i == N - 2 || i == N - 1 || j == M - 1) { for (d = 0; d < 9; d ++) { t1 = i + u[d][0], t2 = j + u[d][1]; if (0 <= t1 && t1 < N && 0 <= t2 && t2 < M) for (k = 0; k < 2 * M + N - 1; k ++) if (eqn[t1][t2][k] == 1) mat[tot][k] ^= 1; } tot ++; } mat[tot ++][2*M+N-2] = 1; vector
res(2 * M + N - 1, 1); for (cnt = tot, i = 0; i < tot; i ++) { for (loc = 0; loc < tot; loc ++) if (mat[i][loc] == 1) break; if (loc >= tot) { if (res[i] == 1) return 0; continue; } for (cnt --, j = i + 1; j < tot; j ++) if (mat[j][loc] == 1) { res[j] ^= res[i]; for (k = 0; k < tot; k ++) mat[j][k] ^= mat[i][k]; } } printf("%d\n", calculatePower(cnt)); return 0; }

游行

【问题描述】

每年春季,在某岛屿上都会举行游行活动。

在这个岛屿上有N个城市,M条连接着城市的有向道路。

你要安排英雄们的巡游。英雄从城市si出发,经过若干个城市,到城市ti结束,需要特别注意的是,每个英雄的巡游的si可以和ti相同,但是必须至少途径2个城市。

每次游行你的花费将由3部分构成:

1.每个英雄游行经过的距离之和,需要特别注意的是,假如一条边被途径了k次,那么它对答案的贡献是k*ci,ci表示这条边的边权。

2.如果一个英雄的巡游的si不等于ti,那么会额外增加C的费用。因为英雄要打的回到起点。

3.如果一个城市没有任何一个英雄途经,那么这个城市会很不高兴,需要C费用的补偿。

你有无数个的英雄。你要合理安排游行方案,使得费用最小。

由于每年,C值都是不一样的。所以你要回答Q个询问,每个询问都是,当C为当前输入数值的时候的答案。

【输入格式】

第一行正整数N,M,Q;

接下来的M行,每行ai,bi,ci,表示有一条从ai到bi,边权为ci的有向道路。保证不会有自环,但不保证没有重边。

接下来Q行,每行一个C,表示询问当每次费用为C时的最小答案。

【输出格式】

Q行,每行代表一个询问的答案。

【样例输入】

6 5 3

1 3 2

2 3 2

3 4 2

4 5 2

4 6 2

1

5

10 

【样例输出】

6

21

32

【样例说明】

第一年的时候,C只有1。我们比较懒所以就不安排英雄出游了,需要支付6的费用。

第二年的时候,我们可以这么安排:

第一个英雄1->3->4->5,需要付2+2+2=6的费用,同时还要花5费用打的回家。再花5+5的费用来补偿2号城市和6号城市。

第三年略。

 

【数据范围】

对于20%的数据,N<=3。

另外40%的数据,Q<=5。

对于100%的数据,2<=N<=250,1<=M<=30000,1<=Q<=10000。

1<=ci<=10000,1<=C<=10000。

这种神题……表示我只会n^3Floyd一下然后就不会做了

正解是:首先Floyd。对于每一个询问,每个点拆点搞成二分图,左边n个右边n个。然后左右连边。对于两个点i , j连容量为1、费用为dist[i][j]的边。一开始费用直接取n*c,就是什么也不取。然后开始匹配,每次匹配之后都会使ans+=V-C。那么则可以分成合并成一个环、合并成树两种。注意到对于一个询问,C是给定的,V是固定的,所以直接预处理出所有增广路,然后读入c直接输出答案就行了

#include
#include
const int N=505,M=130005;int n,m,Q,l=1,S,T,x,y,z,a[N][N],d[N],pre[N],f[M*5],c[M];int st[M],ed[M],data[M],cost[M],next[M],son[N];bool b[N];inline int min(int a,int b){return a
=d[T]) continue; for (int p=son[i];p;p=next[p]) if (data[p]){ int j=ed[p]; if (d[i]+cost[p]>=d[j]) continue; d[j]=d[i]+cost[p]; pre[j]=p; if (!b[j]) b[j]=1,f[++t]=j; } } for (int p=T;p!=S;p=st[p]) p=pre[p],data[p]--,data[p^1]++; return d[T];}int main(){ freopen("parade.in", "r", stdin); freopen("parade.out", "w", stdout); scanf("%d%d%d",&n,&m,&Q); S=0;T=n+n+1; memset(a,6,sizeof(a)); for (int i=1;i<=m;i++) { scanf("%d%d%d",&x,&y,&z); a[x][y]=min(a[x][y],z); } for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) for (int k=1;k<=n;k++) if (a[i][k]+a[k][j]

模板题

【问题描述】

给一个N个点M条边的有向图,求边权和尽量大的一条简单路径。

简单路径的定义是不会经过重点的路径。

【输入格式】

第一行是数据编号。

第一行正整数N,M,表示点数和边数。

接下来的M行,每行a, b, c,表示从a到b一条边权为c的边。

【输出格式】

第一行输出你找到的简单路径的边的个数

接下来若干行输出你的边的下标。边从1开始标号。

【样例输入】

10

3 3

1 2 1

1 3 1

2 3 1

【样例输出】

2

1 3

【样例说明】

1->2,2->3最优。输出边的下标1和3。

【评分标准】

每个点有3个评分标准a1,a2,a3。

如果你的答案>=a1,得10分。

如果你的答案>=a2,得7分。

如果你的答案>=a3,得4分。

如果你的答案>0,得1分。

取能得到的最高的分。

测评方式和昨天一样,过一段时间会放出gen.exe,直接提交graph-upload.cpp即可。

这坑爹啊……首先引用题解对每一个数据点的描述:

0:2*N的网格图。

1:n=14,随便暴力。

2:树。

3:看起来是一棵树,实际上是一棵树加上一个环套树。

4:环套树,随机选取生成树很难A掉。

5:数据规模较小一些的环套树,随机选取多个生成树来做树的情况可以A。

6:环套树随机加上了一些边权为-3000000的边。

7: 仙人掌。

8:DAG。

9:分层图,一层内是一个环。

受到昨天黄巨大随机化70分的影响,我写的就是个随机加边+随机起点+随机退出的骗分,只不过多做几次。但是还是各种wa呀wa

代码太丑没脸见人了……就不贴了

正解是:

对于数据0,dp。

对于数据1,暴力乱搞。

对于数据2,dp。

对于数据3,枚举树上节点搞啊搞

对于数据4,树形dp。

对于数据5,如题解所说枚举生成树乱搞

对于数据6,删边完同3。

对于数据7,不要问我我也不会……关键是我忘了原来黄哥哥说怎么做了

对于数据8,有向无环图什么的随便拓扑排序之类的乱搞吧

对于数据9,这可以保存每层环的状态dp。

没有然后了……

转载于:https://www.cnblogs.com/zhber/p/4036049.html

你可能感兴趣的文章
【架构】Linux的架构(architecture)
查看>>
ASM 图解
查看>>
Date Picker控件:
查看>>
你的第一个Django程序
查看>>
grafana授权公司内部邮箱登录 ldap配置
查看>>
treegrid.bootstrap使用说明
查看>>
[Docker]Docker拉取,上传镜像到Harbor仓库
查看>>
javascript 浏览器类型检测
查看>>
nginx 不带www到www域名的重定向
查看>>
记录:Android中StackOverflow的问题
查看>>
导航,头部,CSS基础
查看>>
[草稿]挂载新硬盘
查看>>
[USACO 2017 Feb Gold] Tutorial
查看>>
关于mysql中GROUP_CONCAT函数的使用
查看>>
OD使用教程20 - 调试篇20
查看>>
Java虚拟机(JVM)默认字符集详解
查看>>
Java Servlet 过滤器与 springmvc 拦截器的区别?
查看>>
(tmp >> 8) & 0xff;
查看>>
linux命令之ifconfig详细解释
查看>>
NAT地址转换
查看>>