NOIP 模拟赛

思路:求 n , m 的 gcd,然后用 n , m 分别除以 gcd;若 n 或 m 为偶数,则输出 1/2.

  特别的,当 n = m = 1 时,应输出 1/1

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
typedef long long LL;
LL n, m; LL gcd(LL x, LL y) {
return y == ? x : gcd(y, x % y);
} int main() {
freopen("line.in","r",stdin);
freopen("line.out","w",stdout);
cin >> n >> m;
if (n == m && m == ) return printf("1/1\n"), ;
LL tmp = gcd(n, m);
n /= tmp; m /= tmp;
if (!(n & ) || !(m & )) return printf("1/2\n"), ; fclose(stdin); fclose(stdout);
return ;
}

考场代码

正解:题目要求的是比值,故当 m 与 n 不互质时,我们可以求出 m 和 n 的最大公约数 d,并将 m /= d, n /= d,并不影响结果。故我们现在假定 m 和 n 互质。若m 和 n 中有一个为偶数, 那么根据对称性, 答案就是 1/2。 如果 m 和 n 均为奇数,那么答案就是(n*m+1) / (2*m*n)。

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long LL;
LL n, m, d; LL gcd(LL x, LL y) {
return x % y ? gcd(y, x % y) : y;
} int main() {
freopen("line.in","r",stdin);
freopen("line.out","w",stdout);
cin >> n >> m;
d = gcd(n, m);
n /= d, m /= d;
if ((n + m) & ) cout << "1/2" << endl;
else cout << (n * m + ) / << "/" << n * m << endl;
return ;
}

正解

思路:线段树维护是否有浓雾。一开始都没有,建树时每个位置的值都赋为 1;若进行 1 或 2 操作,用 flag 标记,因为是区间直接赋值,所以两种操作只需要一个标记即可。查询写错了,导致100 -> 10,对题意理解稍有偏差。

#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
const int N = ;
int n, m, k, x, y;
struct nond {
int ll, rr;
int sum;
int flag;
} tree[N << ]; inline void update(int now) {
tree[now].sum = tree[now << ].sum + tree[now << | ].sum;
} inline void down(int now) {
if (tree[now].flag == ) {
tree[now << ].flag = ;
tree[now << | ].flag = ;
tree[now << ].sum = tree[now << ].rr - tree[now << ].ll + ;
tree[now << | ].sum = tree[now << | ].rr - tree[now << | ].ll + ;
}
else {
tree[now << ].flag = -;
tree[now << | ].flag = -;
tree[now << ].sum = ;
tree[now << | ].sum = ;
}
tree[now].flag = ;
return ;
} inline void build(int now, int l, int r) {
tree[now].ll = l; tree[now].rr = r;
tree[now].flag = ; tree[now].sum = ;
if (l == r) return ;
int mid = (l + r) >> ;
build(now << , l, mid);
build(now << | , mid + , r);
update(now);
} inline void change(int now, int l, int r) {
if (tree[now].ll == l && tree[now].rr == r) {
tree[now].flag = -;
tree[now].sum = ;
return ;
}
if (tree[now].flag != ) down(now);
int mid = (tree[now].ll + tree[now].rr) >> ;
if (l <= mid && mid < r) change(now << , l, mid), change(now << | , mid + , r);
else if (r <= mid) change(now << , l, r);
else change(now << | , l, r);
update(now);
} inline void become(int now, int l, int r) {
if (tree[now].ll == l && tree[now].rr == r) {
tree[now].flag = ;
tree[now].sum = tree[now].rr - tree[now].ll + ;
return ;
}
if (tree[now].flag != ) down(now);
int mid = (tree[now].ll + tree[now].rr) >> ;
if (l <= mid && mid < r) become(now << , l, mid), become(now << | , mid + , r);
else if (r <= mid) become(now << , l, r);
else become(now << | , l, r);
update(now);
} inline int query(int now, int l, int r) {
if (tree[now].ll == l && tree[now].rr == r)
return tree[now].sum;
if (tree[now].flag != ) down(now);
int mid = (tree[now].ll + tree[now].rr) >> ;
if (l <= mid && mid < r) return query(now << , l, mid) + query(now << | , mid + , r);
else if (r <= mid) return query(now << , l, r);
else return query(now << | , l, r);
} int main() {
freopen("explore.in","r",stdin);
freopen("explore.out","w",stdout);
scanf("%d%d", &n, &m);
build(, , n);
for (int i = ; i <= m; ++i) {
scanf("%d%d", &k, &x);
if (k == ) { scanf("%d", &y); change(, x, y); }
else if (k == ) { scanf("%d", &y); become(, x, y); }
else {
if (query(, x, x) == ) printf("0\n");
else {
if (query(, , x) == x || query(, x, n) == n - x + )
printf("INF\n");
else for (int j = ; j <= (n >> ); ++j) {
int tmp = query(, x - j, x + j);
if (tmp != j << | ) { printf("%d\n", tmp); break; }
}
}
}
}
fclose(stdin); fclose(stdout);
return ;
}

考场代码

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#define fortodo(i, f, t) for (i = f; i <= t; i++)
using namespace std; int lsd[], rsd[], lsid[], rsid[], cov[], segsize;
bool emp[]; int SEG_Build(int L, int R) {
int Nid = ++segsize;
lsd[Nid] = L;
rsd[Nid] = R;
emp[Nid] = true;
cov[Nid] = ;
if (L == R) lsid[Nid] = rsid[Nid] = -;
else {
lsid[Nid] = SEG_Build(L, (L + R) / );
rsid[Nid] = SEG_Build((L + R) / + , R);
};
return Nid;
}; bool SEG_Empty(int Nid) {
if (cov[Nid] == ) return true;
if (cov[Nid] == ) return false;
return emp[Nid];
}; void SEG_Reemp(int Nid) {
emp[Nid] = SEG_Empty(lsid[Nid]) && SEG_Empty(rsid[Nid]);
}; void SEG_Inherit(int Nid) {
if (cov[Nid] == -) return;
if (lsd[Nid] == rsd[Nid]) return;
cov[lsid[Nid]] = cov[Nid];
cov[rsid[Nid]] = cov[Nid];
cov[Nid] = -;
SEG_Reemp(Nid);
}; void SEG_Paint(int Nid, int L, int R, int Color) {
SEG_Inherit(Nid);
if ((L == lsd[Nid]) && (R == rsd[Nid])) {
cov[Nid] = Color;
return;
};
int Div = (lsd[Nid] + rsd[Nid]) / ;
if (L > Div) SEG_Paint(rsid[Nid], L, R, Color);
if (R <= Div) SEG_Paint(lsid[Nid], L, R, Color);
if ((L <= Div) && (R > Div)) {
SEG_Paint(lsid[Nid], L, Div, Color);
SEG_Paint(rsid[Nid], Div + , R, Color);
};
SEG_Reemp(Nid);
}; bool SEG_Query(int Nid, int L, int R) {
SEG_Inherit(Nid);
if (SEG_Empty(Nid)) return true;
if ((L == lsd[Nid]) && (R == rsd[Nid])) return SEG_Empty(Nid);
int Div = (lsd[Nid] + rsd[Nid]) / ;
if (L > Div) return SEG_Query(rsid[Nid], L, R);
if (R <= Div) return SEG_Query(lsid[Nid], L, R);
return SEG_Query(lsid[Nid], L, Div) && SEG_Query(rsid[Nid], Div + , R);
}; int S, Q;
int i, j;
int Opt, X, Y; void Answer(int P) {
if (!SEG_Query(, P, P)) {
printf("0\n");
return;
};
if ((SEG_Query(, , P)) || (SEG_Query(, P, S))) {
printf("INF\n");
return;
};
int L, R, M, Ans[];
L = ; R = P;
while (L < R) {
M = (L + R) / ;
if (SEG_Query(, M, P)) R = M;
else L = M + ;
};
Ans[] = L;
L = P; R = S - ;
while (L < R) {
M = (L + R + ) / ;
if (SEG_Query(, P, M))
L = M;
else
R = M - ;
};
Ans[] = L;
printf("%d\n", Ans[] - Ans[] + );
}; int main() {
freopen("explore.in", "r", stdin);
freopen("explore.out", "w", stdout);
scanf("%d%d", &S, &Q);
segsize = ;
SEG_Build(, S);
fortodo(i, , Q) {
scanf("%d%d", &Opt, &X);
if (Opt != ) scanf("%d", &Y);
if (Opt == ) SEG_Paint(, X, Y, );
if (Opt == ) SEG_Paint(, X, Y, );
if (Opt == ) Answer(X);
};
return ;
};

正解

思路:

  1.暴搜  写挂了,样例都过不了

  2.树形DP  不会写 后来讲题时发现自己想法是错的

  3.并查集  将直接连接两个有苹果的节点的边打上标记,记录边权和,但仍会存在多个苹果间接相连的情况,没有想到解决办法

然后我就交了唯一一个过了样例但是最不靠谱的 3

然后就暴零了 T^T。。。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int M = ;
int n, m, tot;
int t[M], fc[M];
int fa[M], f[M];
struct nond {
int u, v, w;
int flag;
}e[M]; int find(int x) {
return fa[x] == x ? x : fa[x] = find(fa[x]);
} bool flag = false;
inline void dfs(int now) { //可以明显看到没写完 因为不会写了 qwq
if (f[now] == ) flag = ; } long long ans;
int main() {
freopen("apple.in","r",stdin);
freopen("apple.out","w",stdout);
scanf("%d%d", &n, &m);
for (int i = ; i < n; ++i) fa[i] = i;
for (int i = ; i < n; ++i) {
scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].w);
e[i].flag = ;
}
for (int i = ; i <= m; ++i) {
scanf("%d", &t[i]);
f[t[i]] = ;
}
for (int i = ; i < n; ++i) {
if (f[e[i].u] == && f[e[i].v] == ) {
e[i].flag = ;
ans += e[i].w;
++tot;
continue;
}
int x = find(e[i].u), y = find(e[i].v);
fa[x] = y; }
if (tot == m - ) cout << ans;
else {
for (int i = ; i < n; ++i)
++fc[find(i)];
for (int i = ; i < n; ++i) {
if (fc[i] > ) dfs(i);
if (tot == m - ) break;
}
cout << ans;
}
fclose(stdin); fclose(stdout);
return ;
}

考场代码

正解:

  

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#define REP(i, n) for (int i = 0; i < (n); ++i)
#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
#define ROF(i, a, b) for (int i = (a); i >= (b); --i)
#define FEC(p, u) for (edge *p = G.head[u]; p; p = p->nxt)
using namespace std;
typedef long long LL;
LL inf = 1LL<<; int n, rt;
bool a[];
LL f[], g[]; struct edge {
int b, len;
edge *nxt;
} e[], *le;
struct graph {
edge *head[];
void init() {
le = e;
REP(i, n) head[i] = NULL;
}
void add(int x, int y, int z) {
le->b = y, le->len = z, le->nxt = head[x], head[x] = le++;
}
} G; int fa[];
LL pre[];
int q[];
void init() {
int k, u, v, w;
scanf("%d%d", &n, &k);
G.init();
REP(i, n-) {
scanf("%d%d%d", &u, &v, &w);
G.add(u, v, w);
G.add(v, u, w);
}
while (k--) {
scanf("%d", &u);
a[u] = true;
}
rt = u;
} void bfs() {
int R = ;
q[] = rt;
REP(L, n)
FEC(p, q[L]) if (p->b != fa[q[L]]) {
fa[p->b] = q[L];
pre[p->b] = p->len;
q[++R] = p->b;
}
} void work() {
ROF(i, n - , ) {
int x = q[i];
if (a[x]) {
FEC(p, x) if (p->b != fa[x]) g[x] += f[p->b];
f[x] = g[x]+pre[x];
}
else {
FEC(p, x) if (p->b != fa[x]) f[x] += f[p->b];
g[x] = inf;
FEC(p, x) if (p->b != fa[x]) g[x] = min(g[x], f[x] - f[p->b] + g[p->b]);
f[x] = min(f[x], g[x]+pre[x]);
}
}
} int main() {
freopen("apple.in", "r", stdin);
freopen("apple.out", "w", stdout);
init();
bfs();
work();
cout << f[rt] << endl;
return ;
}

正解

NOIP 模拟赛的更多相关文章

  1. NOIP模拟赛20161022

    NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...

  2. contesthunter暑假NOIP模拟赛第一场题解

    contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...

  3. NOIP模拟赛 by hzwer

    2015年10月04日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...

  4. 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程

    数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...

  5. 队爷的讲学计划 CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的讲学计划 题解:刚开始理解题意理解了好半天,然后发 ...

  6. 队爷的Au Plan CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的Au%20Plan 题解:看了题之后觉得肯定是DP ...

  7. 队爷的新书 CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的新书 题解:看到这题就想到了 poetize 的封 ...

  8. CH Round #58 - OrzCC杯noip模拟赛day2

    A:颜色问题 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2358%20-%20OrzCC杯noip模拟赛day2/颜色问题 题解:算一下每个仆人到它的目的地 ...

  9. CH Round #52 - Thinking Bear #1 (NOIP模拟赛)

    A.拆地毯 题目:http://www.contesthunter.org/contest/CH%20Round%20%2352%20-%20Thinking%20Bear%20%231%20(NOI ...

  10. CH Round #49 - Streaming #4 (NOIP模拟赛Day2)

    A.二叉树的的根 题目:http://www.contesthunter.org/contest/CH%20Round%20%2349%20-%20Streaming%20%234%20(NOIP 模 ...

随机推荐

  1. Linux下查询CPU 缓存的工具

    在Linux下能够使用例如以下工具查询CPU缓存: 方式1: $ lscpu L1d cache: 32K <span style="white-space:pre"> ...

  2. mysql-数据分组

    一.创建分组 上面所讲的语句都是建立在表的所有数据或匹配特定的where子句的数据上进行的.是否能够进行分组,在进行汇总计算哪儿?例如:要想返回每个供应商提供的产品数目怎么办? 分组是在select语 ...

  3. 5. MongoDB基本操作语句

    转自:http://blog.51cto.com/shanqiangwu/1653577 #MongoDB中有三元素:数据库,集合,文档,其中“集合”就是对应关系数据库中的“表”,“文档”对应“行”. ...

  4. 【DotNetNuke介绍】

    简介 DotNetNuke(以下简称DNN)的最终目的是创建一个门户的框架平台,这个平台可以为开发者增添模块搭建应用程序提供坚实的可靠的支持.应用程序的一个关键的功能就是数据存取..NET Frame ...

  5. CUDA笔记(九)

    找了不知道多少教程,终于找到靠谱的nsight的: http://blog.csdn.net/mysniper11/article/details/8003644 还有两个视频的相关: http:// ...

  6. PostgreSQL Replication之第七章 理解Linux高可用(2)

    7.2 衡量可用性 可用性是提供商试图保证一定的可用性级别和客户可以期望的可用性或更多.在某些情况下(取决于服务合同) 收取罚款或减少申购费用是意外停机的原因. 可用性的质量使用百分数来衡量:例如,9 ...

  7. codeforces 400 D Dima and Bacteria【并查集 Floyd】

    题意:给出n个点,分别属于k个集合,判断每个集合里面的点的距离都为0,为0的话输出yes,并输出任意两个集合之间的最短路 这道题目有两个地方不会处理, 先是n个点,分别属于k个集合,该怎么记录下来这里 ...

  8. 如何知道 CPU 是否支持虚拟化技术(VT)

    作者: Sk 译者: LCTT geekpi 我们已经知道如何检查你的 Linux 操作系统是 32 位还是 64 位以及如何知道你的 Linux 系统是物理机还是虚拟机.今天,我们将学习另一个有用的 ...

  9. fill,fill-n,memset的区别

    这里在网上搜集归纳了一个总结 memset函数 按照字节填充某字符 在头文件<string.h>中 因为memset函数按照字节填充,所以一般memset只能用来填充char型数组,(因为 ...

  10. 如何使 nginx 支撑更高并发

    /** * * * * 如何使 nginx 支撑更高的并发? * 原理: * 服务器方面可以从两个方面阐述: * 1.socket 链接方面:因为每次请求都是一次连接,而 nginx 服务器配置方面默 ...