T1大美江湖(洛谷P5006)

zayの题解:

这个题的本质是模拟

不过有卡ceil的地方

ceil是对一个double进行向上取整,而对于int/int来说,返回值是int

举个生动的栗子

ceil(5/3)=1  因为5是int,3是int,所以5/3返回1,对1向上取整为1

正确写法:ceil(1.0*5/3)  返回2

直接上AC代码(向上取整手写的)

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
int n,m,hpe,ste,dee,x,y,stp,dep,q,sunshi;
char c[105][105];
int main()
{   freopen("mzq.in","r",stdin);//输入输出文件差点错了要凉 freopen("mzq.out","w",stdout);scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){scanf("%s",c[i]+1);}scanf("%d%d%d",&hpe,&ste,&dee);scanf("%d%d",&x,&y);scanf("%d%d",&stp,&dep);scanf("%d",&q);for(int i=1;i<=q;i++){ int cz;scanf("%d",&cz);if(cz==1){printf("%d %d %d\n",sunshi,stp,dep);}else{  int di;scanf("%d",&di);if(di==1)y--;if(di==2)y++;if(di==3)x--;if(di==4)x++;if(c[x][y]=='Y')dep+=5;if(c[x][y]=='Q')stp+=5;if(c[x][y]=='R'){sunshi-=10;if(sunshi<0)sunshi=0;}if(c[x][y]=='M'){int rqy1=hpe/(max(1,stp-dee));if(hpe%(max(1,stp-dee)))rqy1++;int rqy2=max(1,ste-dep);sunshi+=max(1,rqy1*rqy2);}  }}return 0;
}

洛谷中对人物的操作是字符形式,改一下就好了

T2:腐草为萤(洛谷P5007)

刚来完一个大模拟,接下来就是大大的懵逼

这玩意咋整啊?咱也不知道咱也不敢问

zayの题解:

我们来理一理思路

像这种选择数加和最大的问题一般有两种解法

1.DP

2.组合数学

-------------zay

这里我们先讲DP(wz太强了,他用组合数学做的,AC了!!!!!)

我们设fx为以x为根时,当前的答案是fx

我们先想一想二叉树(毕竟数据有特殊情况)

这是个一个孩子都没有的二叉树,此时fx为x的权值

这是个有一个孩子的二叉树(下面的小三角是以x的孩子为根的子树)

对于fx,我们可以选x,不选它儿子和下面的子树,答案为x的权值

我们也可以选它儿子u不选它,答案为fu

综上:fx=fu+x的权值

这是一棵有两个儿子的二叉树(三角还是子树)

那么我们肯定可以选u,v,x

再考虑一下u和v能不能进行一番乱搞

显然u的子树里任意一个集合都可以和v进行一番乱搞

那设u子树里的一个集合s的权值是ws,我们再设一个新的变量g,gx为以x为根的子树,所选集合的个数

对于在u子树里的一个集合s,v子树里的任意一个集合与s都能够组成一个新的幼嫩集合

那么u乱搞后对答案的贡献就是Σws*gv,Σws就是fu

同理v乱搞后对答案的贡献就是fv*gu

所以fx=fu+fv+u的权值+fv*gu+fu*gv

那我们再来想一想怎么维护gx

对于没有孩子的点x来说,gx=1(只能和自己搞了qwq)

对于有一个孩子的点x来说,gx=gu(u是x的孩子)+1(可以选u,也可以和自己搞)

对于有两个孩子的点x来说,就有点复杂了

显然可以选u(左孩子),v(右孩子),x(它自己)

再考虑u,v乱搞

对于u子树里的任意一个集合s来说,v子树里的任意一个集合还是都可以和它搞

而u子树里有gu个集合,所以乱搞对gx的贡献是gx*gy

所以gx=gu+gv+1+gu*gv

二叉树讲完了,再考虑不知道多少叉树

假设我们当前遍历到了绿色的这棵子树,参考搞二叉树的思路,怎么做呢?

我们不妨把这棵树左边的所有子树当成一个大子树,这样对它来说就可以像搞二叉树一样了

这时候,这个绿色的子树k对答案的贡献就是fk*(gu+gv+gu*gv+1)

讲完dp,再来谈谈wz强大的组合数解法

我们发现之前的gx=gu+gv+gu*gv+1=(gu+1)*(gx+1),这是对于二叉树的计算方法

扩展到n叉树,就是gx=(gu+1)*(gv+1)*(ga+1)*(gb+1).........

同时通过分析样例玄学发现,Σ点n的权值*gn=ans

然后这道题就做完了(wz tql %%%wz orz)

代码自己不会写,上zay大佬的ρωρ

#include <cstdio>//用c++11写的,所以有些神奇的地方qwq

typedef long long int ll;const int maxn = 1000005;
const int MOD = 1000000007;template <typename T>//据大佬说1e5的读入要用getchar()优化
inline void qr(T &x) {char ch;do { ch = getchar(); } while ((ch > '9') || (ch < '0'));do { x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar(); } while ((ch >= '0') && (ch <= '9'));
}int n, T;
int MU[maxn], frog[maxn], gorf[maxn];
bool vis[maxn];struct Edge {int v;Edge *nxt;Edge(const int _v, Edge *h) : v(_v), nxt(h) {}
};
Edge *hd[maxn];void dfs(const int u);int main() {freopen("dzy.in", "r", stdin);freopen("dzy.out", "w", stdout);qr(n); qr(T);if (T) {for (int i = 1; i <= n; ++i) {MU[i] = i;}} else {for (int i = 1; i <= n; ++i) {MU[i] = 1;}}for (int i = 1, u, v; i < n; ++i) {u = v = 0; qr(u); qr(v);hd[u] = new Edge(v, hd[u]);hd[v] = new Edge(u, hd[v]);}dfs(1);printf("%d\n", frog[1] % MOD);return 0;
}void dfs(const int u) {vis[u] = true;//下面开始auto(c++11)(蒟蒻的电脑c++版本过低)for (auto e = hd[u]; e; e = e->nxt) if (!vis[e->v]) {int v = e->v;dfs(v);frog[u] = (frog[u] * (gorf[v] + 1ll) % MOD) + (frog[v] * (gorf[u] + 1ll) % MOD);//frog就是前面的fgorf[u] = (gorf[u] + gorf[v] + (1ll * gorf[u] * gorf[v])) % MOD;//gorf就是g
  }frog[u] = (frog[u] + MU[u]) % MOD;++gorf[u];
}

T3:锦鲤抄(洛谷P5008)

zayの题解:

这道题依旧有小数据

据说小数据是用来搜索骗分的。这道题爆搜怎么搜呢?

我们可以枚举去掉点的顺序,看是否合法,并且在合法的情况中选择最大的那个情况。

这个题中,子任务3的特殊性质是图是一个DAG。(这种特殊性质一般是让你推正解的)

在一个DAG里面,入度不为0的点总是可以被选到,也就是将所有点的点权按从大到小排序后,选出前k个点的选择顺序一定存在。(证明的话,可以找几个DAG选一选)这样子任务3就解决了。(蒟蒻写着写着就RE了)

我们从DAG中推一下正解。因为其他的数据不保证没有环,所以排序选出前k个点就不一定适用了。因为可能选着选着就会选中一个入度为0的点(选完点后要把出边删掉)。那我们可不可以把一个环看做一个巨大的点,然后使整个图形成一个DAG?当然可以(这也是正解)。于是这个题做完了。

蒟蒻不会写代码,只好拿zay的了

#include <cstdio>
#include <algorithm>
#include <functional>
#ifdef ONLINE_JUDGE
#define freopen(a, b, c)
#endiftypedef long long int ll;namespace IPT {//读入优化const int L = 1000000;char buf[L], *front=buf, *end=buf;char GetChar() {if (front == end) {end = buf + fread(front = buf, 1, L, stdin);if (front == end) return -1;}return *(front++);}
}template <typename T>//这个题的数据是1e7左右,要用fread,不然读入完时间就到了
inline void qr(T &x) {char ch = IPT::GetChar(), lst = ' ';while ((ch > '9') || (ch < '0')) lst = ch, ch=IPT::GetChar();while ((ch >= '0') && (ch <= '9')) x = (x << 1) + (x << 3) + (ch ^ 48), ch = IPT::GetChar();if (lst == '-') x = -x;
}const int maxn = 1000006;struct Edge {int v;Edge *nxt;Edge(const int _v, Edge *h) : v(_v), nxt(h) {}
};
Edge *hd[maxn];int n, m, k, vistime, top, scnt;
int MU[maxn], dfn[maxn], low[maxn], stack[maxn], belong[maxn], minv[maxn];//belong统计缩点后每个点的入度(有时候是一个大环的入度)
bool instack[maxn], haveind[maxn];void tarjan(const int u);int main() {freopen("zay.in", "r", stdin);freopen("zay.out", "w", stdout);qr(n); qr(m); qr(k); MU[0] = 2333;for (int i = 1; i <= n; ++i) qr(MU[i]);//读入点权for (int i = 1, u, v; i <= m; ++i) {u = v = 0; qr(u); qr(v);hd[u] = new Edge(v, hd[u]);}for (int i = 1; i <= n; ++i) if (!dfn[i]) {tarjan(i);//缩点,我们待会再扯
  }for (int u = 1; u <= n; ++u) {for (auto e = hd[u]; e; e = e->nxt) if (belong[u] != belong[e->v]) //e->nxt就是找下一条边,如果两个环的入度不相等,就满足排序取前k个点的思路是对的
{haveind[belong[e->v]] = true;//e->v就是e这条边的终点v
    }}for (int i = 1; i <= scnt; ++i) if (!haveind[i]) {MU[minv[i]] = 0;}std::nth_element(MU + 1, MU + 1 + k, MU + 1 + n,//这里是排序(取前k个的写法,也可以sort,不过这个比sort省时间) std::greater<int>());int ans = 0;for (int i = 1; i <= k; ++i) {ans += MU[i];}printf("%d\n", ans);return 0;
}void tarjan(const int u) {//缩点dfn[u] = low[u] = ++vistime;instack[stack[++top] = u] = true;for (auto e = hd[u]; e; e = e->nxt) {int v = e->v;if (!dfn[v]) {tarjan(v);low[u] = std::min(low[u], low[v]);} else if (instack[v]) {low[u] = std::min(low[u], dfn[v]);}}if (dfn[u] == low[u]) {int v, &_mv = minv[++scnt];do {instack[v = stack[top--]] = false;belong[v] = scnt;if (MU[v] < MU[_mv]) _mv = v;} while (v != u);}
}

我们扯一下缩点(Tarjan)

我们先来看一棵十分强大的dfs树(dfs树就是在有向图上,从一个点开始dfs,最终遍历的所有点和边可以构成一棵树,这棵树就是dfs树)

就像上图,从子孙节点指向祖宗节点的边叫返祖边,从一个节点指向兄弟节点的儿子的边叫横叉边,从祖宗节点指向孙子节点的边叫前向边

显然,这三种边中,只有返祖边会形成环,所以我们只要管返祖边就好了。

每个点不好表示,我们可以先给在dfs树上的节点一个编号,保证先遍历到的点的编号小。dfs[n]就是节点n的编号。

我们的目的是找出返祖边,并且把形成环的这一部分弄成一个大点。所以我们再建立一个数组low,low[i]指从i点能够遍历到的在dfs树上最靠上的点的编号(也就是最祖宗的点的编号)

for example(点内的数字是点的编号)

low[4]=1,因为4可以返回到2,2遍历到3,3返回到1

通过low,就可以找到返祖边,进而缩成一个点

程序实现:

将未dfs过的点进行dfs,形成dfs树,并且把遍历到的点入栈,遍历点的出边。low[i]初始化为i。如果有点的出边的终点是之前dfs过的点,则弹栈,一直弹到终点(把终点弹出),将中间所有弹出的点的low设置为终点,并将点权加和。

代码(from zay)

void tarjan(const int u) {//其实就是上面那段代码的最后一部分辣dfn[u] = low[u] = ++vistime;instack[stack[++top] = u] = true;//标记是否在栈里面for (auto e = hd[u]; e; e = e->nxt) {int v = e->v;if (!dfn[v]) {tarjan(v);low[u] = std::min(low[u], low[v]);//这里考虑到v可能会有返祖边,所以取min} else if (instack[v]) {low[u] = std::min(low[u], dfn[v]);//不确保u的返祖边指向的节点比v低
    }}if (dfn[u] == low[u]) {//如果没有形成环,就不缩点int v, &_mv = minv[++scnt];do {instack[v = stack[top--]] = false;belong[v] = scnt;if (MU[v] < MU[_mv]) _mv = v;} while (v != u);//也可以直接写while循环
  }
}

我们再扯点骗分技巧

1.读入优化:

1e3(读入量)及以下:scanf

1e6:getchar,也就是普通的快读

1e7:fread,一个函数,读入整个文件(以字符串的形式)。再手动计算每个数。如果令fread一次只读一个字符,那就成slow slow read了

1e8:骂出题人好了

2.暴力:

暴力主要是搜索和模拟

模拟适用于有关数据结构方面的问题

搜索用的比较多。(在数据随机时跑的贼快)搜索的状态设计一般是当前选到了第几个(在给一些东西,一个选k个的题里面),一旦超过k,就check

3.特别提示:

一般有特殊性质(不是特判送分的特殊性质)时,就是让你通过特殊性质推出正解

墙裂建议大家阅读《骗分导论》

转载于:https://www.cnblogs.com/lcez56jsy/p/11062483.html

校内考试之zay与银临(day1)相关推荐

  1. 6.20校内考试整理——大美江湖腐草为萤锦鲤抄题解

    先安利一下题目作者:一扶苏一 先看第一题: 这道题就是一道简单的模拟题,只要不管一开始的位置,模拟移动与格子对应的触发事件就行了.话不多说,看代码: 1 #include<iostream> ...

  2. 2019.9.14校内考试

    T1: 发现正方形棋盘,其边长为2k(1<k<10),而且2k(1<k<10)-1能被3整除,就想到了分治(主要还是qbzt的老师讲过).每次将大棋盘从中间分成4个正方形的小棋 ...

  3. 华中科技大学计算机自考本科通过率,华中科技大学自考本科怎么样?考试可以在校内考吗?...

    华中科技大学自考本科怎么样?考试可以在校内考吗?自考报考华中科技大学的好不好?华中科技大学的自考本科怎样?考试地点是不是可以在校内考?请看以下内容. 华中科技大学自考本科怎么样? 作为湖北教育考试院官 ...

  4. php 考试座位编排系统,具才考场座次编排系统

    具才考场座次编排系统主要功能是,在单位之间.单位内部考生之间随机排序的条件下,使同单位考生前后不相邻(川字型),左右也不相邻(十字型).亦可使成绩差距大的考生不相邻. 具才考场座次编排系统软件说明 不 ...

  5. 银保监会计算机类专业知识,国家公务员局2019中国银保监会国考内容:计算机类专业知识...

    2019国家公务员考试报名最后一天,想要参加今年国考的朋友们都填好职位了吗?报考了今年国考银保监会的亲们可能要问,银保监会考什么?有哪些专业知识需要复习?下面广东中公教育就为大家整理解读2019国考银 ...

  6. 国考银保监会面试上岸指南-计算机岗

    基本情况 笔者参加2021国家公务员考试,报考职位银保监计算机类职位.通过笔试,进入面试后,经过3个月的准备,结合某公12天12夜国考银保监会面试班+收集历年真题+各平台热门面试课程+计算机基础体系, ...

  7. 帮过网:公务员专业科目考试考什么

    公务员考试专业科目考试是考察报考者是否具备在从事有关工作所必需能力.公务员考试专业科目考试科目如下:公安机关面向社会招录人民警察专业科目考试科目.中国银保监会专业科目笔试考试科目.8个非通用语职位外语 ...

  8. vce数学考试能用计算机,VCE课程资深数学老师Richard WANG:我的VCE数学教学心得体会...

    VCE课程资深数学老师Richard WANG简介: Richard WANG老师就职于墨尔本一所著名私立中学, 该校高考成绩常年都位列全维多利亚州前十名.Richard有着多年为澳大利亚本地学生和华 ...

  9. CTSC 2018 游记

    day0 李总提前一天放假,回家颓整理行李... 然而我... 早上:睡觉... 中午:睡觉... 晚上:睡觉去火车站... 吃了几把鸡,本来想带李总入坑,但他挥手拒绝然后被李总带进了炸金花的坑... ...

最新文章

  1. 李彦宏:正在发生的智能经济 4 大变革 | 赠书
  2. live555 学习笔记
  3. IDEA新建spring boot项目没有Spring Initializr选项
  4. TPC-H生成Spark测试用的伪数据集(转载)
  5. Android学习指南
  6. 零基础入门深度学习(5) - 循环神经网络
  7. solr 3.5 配置及应用(二)
  8. document.addEventListener理解
  9. Python 面向对象(OOP)基本概念
  10. MySQL基础_模糊查询—between and in is null <=>(安全等于)等关建字
  11. vscode 打开函数表_效率倍增!10个超级好用的VScode使用技巧!
  12. redis之列表字典操作
  13. steam第三方授权登录不稳定(openid4java)
  14. 外贸人写开发信会犯的错误,你中了哪几个
  15. Django中filer和get的区别
  16. 图像分割(MATLAB实现)
  17. umi.js的简单理解
  18. Photoshop-颜色的调整
  19. 谭民机器人_科学网—中科院自动化所喻俊志,谭民研究员等:冰雪运动生物力学及其机器人研究进展 - 欧彦的博文...
  20. JavaScript如何截取字符串的最后一位

热门文章

  1. 交叉编译fw_printenv
  2. 分类整理目前国内比较著名的B2C网站[转]
  3. 项目经理--要具备的能力
  4. Matlab图像的噪声处理
  5. Nature:一份全球综合报告显示生物多样性的丧失是生态系统变化的一个主要驱动因素
  6. 共有产权该有退出机制了,否则单身、离婚、变故、继承、拆迁等怎么办?
  7. 直通转发(cut-through)和存储转发(store-and-forward)的区别
  8. 云展网教程 | 如何设置个人主页的隐私?
  9. 带你玩转vue——开发工具的选择
  10. Win10输入法不能使用,只能在浏览器搜索框里输入英文,其它地方都输入不了