今天终于拿到官方数据,兴致勃勃地全 A 了。

Day 1 T1 toy

处理一下正负号加加减减取模乱搞就好了。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std; int read() {
int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
return x * f;
} #define maxn 100010
int n, q;
struct Toy { int tp; char S[15]; } ts[maxn]; int main() {
freopen("toy.in", "r", stdin);
freopen("toy.out", "w", stdout);
n = read(); q = read();
for(int i = 0; i < n; i++) {
int t = read(); scanf("%s", ts[i].S);
if(!t) ts[i].tp = 1;
else ts[i].tp = -1;
}
int p = 0;
while(q--) {
int a = read(), b = read();
if(a) a = 1; else a = -1;
p += a * ts[p].tp * b;
p = (p % n + n) % n;
} printf("%s\n", ts[p].S); return 0;
}

Day 1 T2 running

受到“链”和“S 恒为 1”和“T 恒为 1”的特殊点的启发,我们发现可以将每条链 [Si, Ti] 分成 [Si, Ci] 和 [Ci, Ti] 两条,然后对于一个全部可观测到的链 [Ci, Ti] 将所有 Wi 减去深度是一个定值,对于 [Si, Ci] 的部分所有 Wi 加上深度是一个定值。于是树链剖分再打打标记统计就好了。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std; int read() {
int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
return x * f;
} #define maxn 300010
#define maxm 600010
#define maxs 12000010
int n, q, m, head[maxn], next[maxm], to[maxm], W[maxn];
struct Player {
int s, t, c;
Player() {}
Player(int _, int __): s(_), t(__) {}
} ps[maxn]; void AddEdge(int a, int b) {
to[++m] = b; next[m] = head[a]; head[a] = m;
swap(a, b);
to[++m] = b; next[m] = head[a]; head[a] = m;
return ;
} int fa[maxn], dep[maxn], siz[maxn], son[maxn], top[maxn], pos[maxn], pid[maxn], clo;
void build(int u) {
siz[u] = 1;
for(int e = head[u]; e; e = next[e]) if(to[e] != fa[u]) {
fa[to[e]] = u;
dep[to[e]] = dep[u] + 1;
build(to[e]);
siz[u] += siz[to[e]];
if(siz[son[u]] < siz[to[e]]) son[u] = to[e];
}
return ;
}
void gett(int u, int tp) {
top[u] = tp; pid[++clo] = u; pos[u] = clo;
if(son[u]) gett(son[u], tp);
for(int e = head[u]; e; e = next[e])
if(to[e] != fa[u] && to[e] != son[u]) gett(to[e], to[e]);
return ;
}
int lca(int a, int b) {
int f1 = top[a], f2 = top[b];
while(f1 != f2) {
if(dep[f1] < dep[f2]) swap(f1, f2), swap(a, b);
a = fa[f1]; f1 = top[a];
}
return dep[a] < dep[b] ? a : b;
} struct Info {
int c, fir[maxn], aft[maxs], val[maxs];
void clear() {
c = 0;
memset(fir, 0, sizeof(fir));
return ;
}
void AddInfo(int x, int v) {
val[++c] = v; aft[c] = fir[x]; fir[x] = c;
return ;
}
} add, del;
int tot[maxn<<1], ans[maxn];
void process(int x, int t, int a, int v) {
int f = top[a];
while(f != top[t]) {
add.AddInfo(pos[f], v);
del.AddInfo(pos[a], v);
a = fa[f]; f = top[a];
}
add.AddInfo(pos[t], v);
del.AddInfo(pos[a], v);
return ;
} int main() {
freopen("running.in", "r", stdin);
freopen("running.out", "w", stdout);
n = read(); q = read();
for(int i = 1; i < n; i++) {
int a = read(), b = read();
AddEdge(a, b);
}
for(int i = 1; i <= n; i++) W[i] = read();
for(int i = 1; i <= q; i++) {
int s = read(), t = read();
ps[i] = Player(s, t);
}
build(1);
gett(1, 1); for(int i = 1; i <= n; i++) W[i] -= dep[i];
add.clear(); del.clear(); memset(tot, 0, sizeof(tot));
for(int i = 1; i <= q; i++) {
ps[i].c = lca(ps[i].s, ps[i].t);
process(i, ps[i].c, ps[i].t, dep[ps[i].s] - dep[ps[i].c] - dep[ps[i].c]);
}
for(int i = 1; i <= n; i++) {
for(int e = add.fir[i]; e; e = add.aft[e]) {
int v = add.val[e] + n;
tot[v]++;
}
int u = pid[i];
ans[u] += tot[W[u]+n];
for(int e = del.fir[i]; e; e = del.aft[e]) {
int v = del.val[e] + n;
tot[v]--;
}
} for(int i = 1; i <= n; i++) W[i] += (dep[i] << 1);
add.clear(); del.clear(); memset(tot, 0, sizeof(tot));
for(int i = 1; i <= q; i++)
process(i, ps[i].c, ps[i].s, dep[ps[i].s]);
for(int i = 1; i <= n; i++) {
for(int e = add.fir[i]; e; e = add.aft[e]) {
int v = add.val[e];
tot[v]++;
}
int u = pid[i];
ans[u] += tot[W[u]];
for(int e = del.fir[i]; e; e = del.aft[e]) {
int v = del.val[e];
tot[v]--;
}
} for(int i = 1; i <= q; i++)
if(W[ps[i].c] == dep[ps[i].s]) ans[ps[i].c]--; for(int i = 1; i <= n; i++) printf("%d%c", ans[i], i < n ? ' ' : '\n'); return 0;
}

Day 1 T3 classroom

这题我考场上想到正解但是因为邻接矩阵连边时忘记取 min 就 sb 了。。。。。

设 f[0][i][j] 表示前 i 条请求使用了 j 条,最后一条没取的最小期望距离;f[1][i][j] 表示前 i 条请求使用了 j 条,最后一条取了的最小期望距离。然后因为每次走哪条边是独立的,转移时直接乘上概率累加上就好了。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std; int read() {
int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
return x * f;
} #define maxn 2010
#define maxv 310
#define oo 1000000000
int n, m, v, e, c[maxn], d[maxn], D[maxn][maxn];
double p[maxn], f[2][maxn][maxn]; void up(double& a, double b) {
a = min(a, b);
return ;
} int main() {
freopen("classroom.in", "r", stdin);
freopen("classroom.out", "w", stdout);
n = read(); m = read(); v = read(); e = read();
for(int i = 1; i <= n; i++) c[i] = read();
for(int i = 1; i <= n; i++) d[i] = read();
for(int i = 1; i <= n; i++) scanf("%lf", &p[i]);
for(int i = 1; i <= v; i++) {
D[i][i] = 0;
for(int j = i + 1; j <= v; j++)
D[i][j] = D[j][i] = oo;
}
for(int i = 1; i <= e; i++) {
int a = read(), b = read(), c = read();
D[a][b] = min(D[a][b], c);
D[b][a] = min(D[b][a], c);
}
for(int k = 1; k <= v; k++)
for(int i = 1; i <= v; i++)
for(int j = 1; j <= v; j++)
D[i][j] = min(D[i][j], D[i][k] + D[k][j]); for(int i = 0; i <= n; i++)
for(int j = 0; j <= m; j++) f[0][i][j] = f[1][i][j] = 1e9;
f[0][0][0] = 0.0;
for(int i = 0; i <= n; i++)
for(int j = 0; j <= min(i + 1, m); j++) {
double P = p[i], np = p[i+1], p1 = 1.0 - P, np1 = 1.0 - np;
up(f[0][i+1][j], f[0][i][j] + D[c[i]][c[i+1]]);
up(f[1][i+1][j+1], f[0][i][j] + np * D[c[i]][d[i+1]] + np1 * D[c[i]][c[i+1]]);
up(f[0][i+1][j], f[1][i][j] + P * D[d[i]][c[i+1]] + p1 * D[c[i]][c[i+1]]);
up(f[1][i+1][j+1], f[1][i][j] + P * np * D[d[i]][d[i+1]] + P * np1 * D[d[i]][c[i+1]] + p1 * np * D[c[i]][d[i+1]] + p1 * np1 * D[c[i]][c[i+1]]);
} double ans = 1e9;
for(int i = 0; i <= m; i++) up(ans, min(f[0][n][i], f[1][n][i]));
printf("%.2lf\n", ans); return 0;
}

Day 2 T1 problem

用递推法求组合数,实时模 k。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std; int read() {
int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
return x * f;
} #define maxn 2010
int C[2][maxn], f[maxn][maxn]; int main() {
freopen("problem.in", "r", stdin);
freopen("problem.out", "w", stdout);
int size = 2000;
bool cur = 0;
int T = read(), k = read();
for(int i = 0; i <= size; i++, cur ^= 1) {
C[cur][0] = 1; C[cur][i] = 1;
for(int j = 1; j < i; j++) C[cur][j] = (C[cur^1][j-1] + C[cur^1][j]) % k;
for(int j = 0; j <= i; j++) {
f[i][j] = (!C[cur][j]);
int t = 0;
if(j) f[i][j] += f[i][j-1], t++;
if(j <= i - 1) f[i][j] += f[i-1][j], t++;
if(t == 2 && i && j) f[i][j] -= f[i-1][j-1];
}
}
while(T--) {
int n = read(), m = read();
printf("%d\n", f[n][min(n,m)]);
} return 0;
}

Day 2 T2 earthworm

受到 q = 0 即蚯蚓长度没有增加的数据启发,我们发现每次坎出的两条蚯蚓的长度一定是单调降的,于是可以 O(n) 做了。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std; int read() {
int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
return x * f;
} #define maxn 100010
#define maxm 7100010
#define LL long long
int n, m, q, u, v, t, A[maxn], B[maxm], C[maxm], lb, rb, lc, rc, ans[maxm], cnt; bool cmp(int a, int b) { return a > b; } void process(int tmp, int i, int len) {
int nb = (LL)tmp * u / v, nc = tmp - nb;
B[++rb] = nb - len - q;
C[++rc] = nc - len - q;
if(i % t == 0) ans[++cnt] = tmp;
return ;
} int main() {
freopen("earthworm.in", "r", stdin);
freopen("earthworm.out", "w", stdout);
n = read(); m = read(); q = read(); u = read(); v = read(); t = read();
for(int i = 1; i <= n; i++) A[i] = read();
sort(A + 1, A + n + 1, cmp);
// for(int i = 1; i <= n; i++) printf("%d%c", A[i], i < n ? ' ' : '\n'); lb = 1; rb = 0; lc = 1; rc = 0;
int pa = 1, len = 0;
for(int i = 1; i <= m; i++, len += q) {
int a, b, c;
a = (pa <= n) ? A[pa] + len : -1;
b = (lb <= rb) ? B[lb] + len : -1;
c = (lc <= rc) ? C[lc] + len : -1;
if(a >= b && a >= c) {
pa++;
process(a, i, len);
}
else if(b >= a && b >= c) {
lb++;
process(b, i, len);
}
else {
lc++;
process(c, i, len);
}
}
for(int i = 1; i <= cnt; i++) printf("%d%c", ans[i], i < cnt ? ' ' : '\n');
if(!cnt) putchar('\n');
cnt = 0;
for(int i = 1; i <= n + m; i++) {
int a, b, c;
a = (pa <= n) ? A[pa] + len : -1;
b = (lb <= rb) ? B[lb] + len : -1;
c = (lc <= rc) ? C[lc] + len : -1;
if(a >= b && a >= c) {
pa++;
if(i % t == 0) ans[++cnt] = a;
}
else if(b >= a && b >= c) {
lb++;
if(i % t == 0) ans[++cnt] = b;
}
else {
lc++;
if(i % t == 0) ans[++cnt] = c;
}
}
for(int i = 1; i <= cnt; i++) printf("%d%c", ans[i], i < cnt ? ' ' : '\n');
if(!cnt) putchar('\n'); return 0;
}

Day 2 T3 angrybirds

状压 dp,设 f[S] 表示干掉集合 S 的猪需要的最少抛物线条数,转移时找到第一个没有被干掉的猪,再枚举另一头猪,两点确定一条过 (0, 0) 的抛物线,然后转移到当前集合与抛物线经过猪的集合的并集。注意到每条抛物线经过猪的集合是可以预处理的。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <cmath>
using namespace std; int read() {
int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
return x * f;
} #define maxn 23
#define maxs 362154
const double eps = 1e-6;
struct Point {
double x, y;
Point() {}
Point(double _, double __): x(_), y(__) {}
bool operator < (const Point& t) const { return x != t.x ? x < t.x : y < t.y; }
} ps[maxn];
int f[maxs], ls[maxn][maxn]; bool on(double a, double b, Point p) {
return fabs(a * p.x * p.x + b * p.x - p.y) <= eps;
} void up(int& a, int b) {
if(a < 0) a = b;
else a = min(a, b);
return ;
} int main() {
freopen("angrybirds.in", "r", stdin);
freopen("angrybirds.out", "w", stdout);
int T = read();
while(T--) {
int n = read(); read();
for(int i = 0; i < n; i++) scanf("%lf%lf", &ps[i].x, &ps[i].y);
sort(ps, ps + n);
memset(f, -1, sizeof(f));
memset(ls, 0, sizeof(ls));
f[0] = 0;
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++) if(i != j) {
double x1 = ps[i].x, y1 = ps[i].y, x2 = ps[j].x, y2 = ps[j].y;
double b = (x1 * x1 * y2 - x2 * x2 * y1) / (x1 * x1 * x2 - x2 * x2 * x1);
double a = (y1 - b * x1) / (x1 * x1);
if(a >= 0.0) continue;
int S = 0;
for(int k = 0; k < n; k++) if(((S >> k & 1) ^ 1) && on(a, b, ps[k]))
S |= (1 << k);
ls[i][j] = S;
}
int all = (1 << n) - 1;
for(int S = 0; S <= all; S++) if(f[S] >= 0)
for(int j = 0; j < n; j++) if((S >> j & 1) ^ 1) {
int tS = S | (1 << j);
up(f[tS], f[S] + 1);
for(int i = j + 1; i < n; i++) if((tS >> i & 1) ^ 1)
up(f[tS | ls[i][j]], f[S] + 1);
break;
}
printf("%d\n", f[all]);
} return 0;
}

这次 NOIP 为什么都是第二题最难 TAT

NOIP2016题目整合的更多相关文章

  1. NOIP2016提高组解题报告

    NOIP2016提高组解题报告 更正:NOIP day1 T2天天爱跑步 解题思路见代码. NOIP2016代码整合

  2. 201621123033 《Java程序设计》第6周学习总结

    第六次作业 1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图或相关笔记,对面向对象思想进行一个总结. 2. 书面作业 1. clone方法 ...

  3. NOIp2016 Day1&Day2 解题报告

    Day1 T1 toy 本题考查你会不会编程. //toy //by Cydiater //2016.11.19 #include <iostream> #include <cstd ...

  4. NOIp2016 游记

    DAY -2 不要问我为什么现在就开了一篇博客. 本来想起个NOIp2016爆零记或者NOIp2016退役记之类的,但是感觉现在不能乱立flag了.所以就叫游记算了. 前几场模拟赛崩了一场又一场,RP ...

  5. 【Java EE 学习 74 下】【数据采集系统第六天】【使用Jfreechart的统计图实现】【将JFreechart整合到项目中】

    之前说了JFreechart的基本使用方法,包括生成饼图.柱状统计图和折线统计图的方法.现在需要将其整合到数据采集系统中根据调查结果生成三种不同的统计图. 一.统计模型的分析和设计 实现统计图显示的流 ...

  6. NOIP2016普及总结

    ---恢复内容开始--- 当时我说如果不出意外有385,结果就这么跪在了第二题,惨啊 本来以为发挥算正常,结果这发挥太不正常了 [T1] 水题啊[趴 注意下细节就好考你会不会写代码. [T2] 这题大 ...

  7. 游记——noip2016

    2016.11.18 (day 0) 呆在家. 悠闲地呆在家.. 明后天可能出现的错误: 1)没打freopen.打了ctime: 2)对拍程序忘记怎么写了...忘记随机化种子怎么写了: 3)不知道厕 ...

  8. 题目1380:lucky number

    转载请注明文本链接 http://blog.csdn.net/yangnanhai93/article/details/40441709 题目链接地址:http://ac.jobdu.com/prob ...

  9. 把angular项目整合到.net mvc中

    之前的开发选择的是完全舍弃服务端,仅保留最简单web服务器提供angular经打包的静态资源,此外所有的业务与数据请求都访问一个分离的WebApi来实现.不过最近碰到一个需求,有必要使用多个客户端,而 ...

随机推荐

  1. easyUI validate函数【总结篇-部分转】

    以下是自己总结和修改别人的帖子和资源整理出来的一些常用验证函数,备用,交流. <body>邮箱验证:<input type="text" validtype=&q ...

  2. HTML学习笔记——列表和table

    1>有序列表.无序列表和自定义列表 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" &qu ...

  3. Android学习笔记——SQLite

    该工程的功能是实现关于数据库的操作,即creat.update.insert.query.delete 调试的时候请用模拟器,用真机调试的时候进入cmd-adb shell,再进入cd data/da ...

  4. 端口扫描(TCP)

    还待优化... #include <string.h> #include <WinSock.h> #include <stdio.h> #pragma commen ...

  5. Swift学习一

    // 定义一个类 class AClass { } // 数据转换 var a = Int(4.555) // 可选值 var num: Int? = Int("23k") // ...

  6. MySQL-curses/termcap缺失

    环境:通前篇 1.错误:缺少 /curses/temrcap checking for termcap functions library... configure: error: No curses ...

  7. DESCryptoServiceProvider

    public static byte[] DESEncrypt(byte[] data, byte[] sKey) { return DESEncrypt(data, sKey, sKey); } / ...

  8. Semantic ui 学习笔记 持续更新

    这个semantic 更新版本好快~ 首先是代码的标识<code></code> 具体样式就是红框这样的 圈起来代码感觉不错 不过要在semantic.css里在加上如下样式~ ...

  9. "Java 反序列化"过程远程命令执行漏洞

    一.漏洞描述   国外 FoxGlove 安全研究团队于2015年11月06日在其博客上公开了一篇关于常见 Java 应用如何利用反序列化操作进行远程命令执行的文章.原博文所提到的 Java 应用都使 ...

  10. python 文件包含

    Python的import包含文件功能就跟PHP的include类似,但更确切的说应该更像是PHP中的require,因为Python里的import只要目标不存在就报错程序无法往下执行.要包含目录里 ...