6.20校内考试整理——大美江湖&&腐草为萤&&锦鲤抄题解
先安利一下题目作者:一扶苏一
先看第一题:
这道题就是一道简单的模拟题,只要不管一开始的位置,模拟移动与格子对应的触发事件就行了。话不多说,看代码:
#include<iostream>
#include<cstdio>
#include<cctype>
#include<cmath> using namespace std; int n,m,myst,myde,hisst,hisde,hishp,lshp,ans,stax,stay;
int wyx[]={,,,-,+},wyy[]={,-,,,};//位移增量 char mp[][],ch; inline int read()
{
ans=;
ch=getchar();
while(!isdigit(ch)) ch=getchar();
while(isdigit(ch)) ans=(ans<<)+(ans<<)+ch-'',ch=getchar();
return ans;
} int main()
{
freopen("mzq.in","r",stdin);
freopen("mzq.out","w",stdout);
n=read(),m=read();
for(int i=;i<=n;i++)
scanf("%s",mp[i]+);
hishp=read(),hisst=read(),hisde=read();
stax=read(),stay=read();//目前位置
myst=read(),myde=read();
int q,a,b;
q=read();
while(q--)
{
a=read();
if(a==)//查询操作
{
printf("%d %d %d\n",lshp,myst,myde);
}
else
{
b=read();
stax+=wyx[b];stay+=wyy[b];//模拟移动
switch(mp[stax][stay])//模拟触发事件
{
case '.':break;
case 'R':
lshp-=;
if(lshp<) lshp=;
break;
case 'Q':myst+=;break;
case 'Y':myde+=;break;
case 'M':lshp+=max(,(int)ceil(hishp/(double)max(,myst-hisde)))*max(,hisst-myde);
break;
}
}
}
return ;
}
再看第二题:
爆搜显然是得不了全分的。我们从最简单的情况看起:
假如一棵树只有一个根节点u,那么答案就是uT;
如果 u 只有一个孩子 v,那么要么选 u 不选 u 的子孙,要么不选 u。不妨设以节点x为根的树的答案为fx,则不选 u 的答案即为 fv,选 u 的答案即为 uT。两种情况加起来就是 fu;
如果 u 有两个孩子 x,y。考虑要么选 u,要么只选 x 的子树内的元素,要么 只选 y 的子树内的元素,要么既选 x 内的元素又选 y 内的元素但不选 u。设 s 是 x 子树内的某个集合。考虑无论在y 的子树内怎么选,再加上 s 都是合法的,因为 y 和 x 之间没有祖先后代关系且 s 在 x 之内。设 gu 是以 u 为根能选择的集合个数,那么一共有 gy 个 集合选择 s 以后依旧合法,设 s 的权值和为 Ws,于是 s 的贡献即为 Ws×gy。由于 fx 为 x 子树内所有可能集合的权值和,所以可以发现在以x为根的子树里所有集合s的权值和为fx。于是 x 子树内的集合对答案的总贡献是 fx×gy。同理,y 子树内的集合对答案的贡献是 fy×gx。 于是 fu=fy×gx+fx×gy+fx+fy+uT。gu=gx×gy+gx+gy+1。
考虑u又有一个孩子z,那么可以把u前面的孩子看做一个子树(仔细想一下f和g的含义,这样看成整体后可以包括在前面儿子选择的所有情况,而这个整体的f即为上文中关于f的式子不加根uT的情况,g就是上文不加1的情况),那么情况就同上面第三种情况了。
见std标程:
#include<iostream>
#include<cstdio>
#define int long long int namespace IPT {
const int L = ;
char buf[L], *front=buf, *end=buf;
char GetChar() {
if (front == end) {
end = buf + fread(front = buf, , L, stdin);
if (front == end) return -;
}
return *(front++);
}
} template <typename T>
inline void qr(T &x) {
char ch = IPT::GetChar(), lst = ' ';
while ((ch > '') || (ch < '')) lst = ch, ch=IPT::GetChar();
while ((ch >= '') && (ch <= '')) x = (x << ) + (x << ) + (ch ^ ), ch = IPT::GetChar();
if (lst == '-') x = -x;
} struct Node{
int nxt,to;
}e[<<];
int head[<<];
int cnt;
int n,T;
int f[];
int g[];
int w[];
const int Mod=;
inline void addedge(int u,int v){
e[++cnt].nxt=head[u];
e[cnt].to=v;
head[u]=cnt;
}
inline void dfs(int x,int fa){
for(register int i=head[x];i;i=e[i].nxt){
int v=e[i].to;
if(v==fa) continue;
dfs(v,x);
f[x]=(f[x]*g[v]+f[v]*g[x]+f[v]+f[x])%Mod;
g[x]=(g[x]*g[v]+g[x]+g[v])%Mod;
}
f[x]=(f[x]+w[x])%Mod;
g[x]=(g[x]+)%Mod;
}
signed main(){
freopen("dzy.in","r",stdin);
freopen("dzy.out","w",stdout);
qr(n); qr(T);
for(register int i=;i<=n;i++) w[i]=T==?i:;
for(register int i=;i<=n-;i++){
int x = ,y = ;
qr(x); qr(y);
addedge(x,y);
addedge(y,x);
}
dfs(,);
std::cout<<f[]<<std::endl;
return ;
}
再看第三题:
(Tip:捆绑测试就是一个子任务由若干个满足子任务要求的测试点组成,只有一个子任务下所有的测试点都过了,才能拿到全分,否则一分不给。)
由于题目中隐隐表达出了一种对每个点的入度的执念,便联想到了拓补排序。爆搜显然拿不到全分了,还是好好分析题目吧。先从简单的情况——DAG开始。对于一个DAG(有向无环图),一定至少有一个拓补排序。所以对一个DAG,除了一开始就入度为0的点,其他点都能通过逆序的拓补排序选上,所以只要把一开始入度不为零的点从大到小排个序,选前k个就行。
对于一个有环的图呢?可以考虑对一个强联通分量“缩点”来转化成DAG的情况,即把一个环看做一个点,那么整张图就可看成一个DAG。这时选点的情况就有两种:一是对整张图的选点,二是对单独一个环里的选点。第一种在上面已经考虑一部分了,这里考虑第二种:一个环如果没有外面的点连向他,即没有入度,那么这个环最少要剩一个点,其他点都可以通过环的搜索树的逆序选上,不妨让环中权值最小的点当那个剩下的点,这样可使局部最优。如果有入度,那么环中的点就有可能都被选。
由上,可知对能被选到的点(DAG中一开始入度不为零的点、环中能被选上的点)排个序,再找前k个就行了。进行一次 tarjan(找环算法)的复杂度是 O(n+m),选前 k 个点可以排序一下。这样总复杂 度 O(m+nlogn)。注意到复杂度瓶颈在排序上,考虑我们只需要前 k 大而不需要具体前 k 个之间的大小关系,于是使用 std::nth_element()函数可 以将复杂度降至 O(n+m)。期望得分 40 分。注意,输入规模到了 107 级别,需要 fread 来实现读入优化。
见STD代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
namespace IPT {
const int L = ;
char buf[L], *front=buf, *end=buf;
char GetChar() {
if (front == end) {
end = buf + fread(front = buf, , L, stdin);
if (front == end) return -;
}
return *(front++);
}
} template <typename T>
inline void qread(T &x) {
char ch = IPT::GetChar(), lst = ' ';
while ((ch > '') || (ch < '')) lst = ch, ch=IPT::GetChar();
while ((ch >= '') && (ch <= '')) x = (x << ) + (x << ) + (ch ^ ), ch = IPT::GetChar();
if (lst == '-') x = -x;
} template<typename sp>
inline sp mmax(sp a,sp b){
return a>b?a:b;
}
template<typename sp>
inline sp mmin(sp a,sp b){
return a>b?b:a;
}
struct Node{
int nxt,from,to;
}e[];
int n,m,k,rd[];
int dfn[],low[],p[];
int head[],cnt,top,s[],sta[];
int tim;
bool vis[];
int minp[];
int ans;
void tarjan(int x){
dfn[x]=low[x]=++tim;
vis[x]=true;
sta[++top]=x;
for(register int i=head[x];i;i=e[i].nxt){
int v=e[i].to;
if(!dfn[v]){
tarjan(v);
low[x]=mmin(low[x],low[v]);
}
else if(vis[v]) low[x]=mmin(low[x],dfn[v]);
}
if(dfn[x]==low[x]){
while(true){
int y=sta[top--];
s[y]=x;
vis[y]=false;
if(p[y]<p[minp[x]]) minp[x]=y;
if(x==y) break;
}
}
}
inline void addedge(int u,int v){
e[++cnt].nxt=head[u];
e[cnt].from=u;
e[cnt].to=v;
head[u]=cnt;
}
int main(){
freopen("zay.in","r",stdin);
freopen("zay.out","w",stdout);
qread(n);qread(m);qread(k);
for(register int i=;i<=n;i++) qread(p[i]);
for(register int i=;i<=n;i++) minp[i]=i;
for(register int i=;i<=m;i++){
int x=,y=;
qread(x);qread(y);
addedge(x,y);
}
for(register int i=;i<=n;i++){
if(!dfn[i]) tarjan(i);
}
for(register int i=;i<=m;i++){
int u=s[e[i].from],v=s[e[i].to];
if(u==v) continue;
rd[v]++;
}
for(register int i=;i<=n;i++) if(s[i]==i&&!rd[i]) p[minp[i]]=;
std::sort(p+,p++n);
//for(register int i=1;i<=n;i++) printf("%d ",p[i]);
for(register int i=;i<=k;i++) ans+=p[n-i+];
std::cout<<ans<<std::endl;
return ;
}
6.20校内考试整理——大美江湖&&腐草为萤&&锦鲤抄题解的更多相关文章
- 模拟赛DAY1 T2腐草为萤
2.腐草为萤(dzy.cpp/c) [题目背景] 纤弱的淤泥中妖冶颓废在季夏第三月最幼嫩的新叶连凋零都不屑何必生离死别——银临<腐草为萤> [问题描述] 扶苏给了你一棵树,这棵树上长满了幼 ...
- 【6.20校内test】
反正考的不是很好吧,赶脚炸了啊qwq 然后这两天一直在忙一些神奇的事情,所以没有整理完 手动@water_lift T1:大美江湖: [题目背景] 细雪飘落长街,枫叶红透又一年 不只为故友流连,其实我 ...
- 2019.6.20 校内测试 NOIP模拟 Day 1 分析+题解
这次是zay神仙给我们出的NOIP模拟题,不得不说好难啊QwQ,又倒数了~ T1 大美江湖 这个题是一个简单的模拟题. ----zay 唯一的坑点就是打怪的时候计算向上取整时,如果用ceil函数一 ...
- 校内考试之zay与银临(day1)
T1大美江湖(洛谷P5006) zayの题解: 这个题的本质是模拟 不过有卡ceil的地方 ceil是对一个double进行向上取整,而对于int/int来说,返回值是int 举个生动的栗子 ceil ...
- 2018.6.20 Java考试试题总结(Java语言基础与面向对象编程)最新版
Java考试试题总结 一.单选题(每题1分 * 50 = 50分) 1.java程序的执行过程中用到一套JDK工具,其中javac.exe指( B ) A.java语言解释器 B.java字节码编译器 ...
- 6.25考试整理:江城唱晚&&不老梦&&棠梨煎雪——题解
按照旧例,先安利一下主要作者:一扶苏一 以及扶苏一直挂念的——银临姐姐:银临_百度百科 (滑稽) 好哒,现在步入正题: 先看第一题: 题解: 在NOIP范围内,看到“求方案数”,就说明这个题是一个计数 ...
- LuoguP5006 [yLOI2018] 大美江湖 题解
Content 题意实在是太过复杂了,因此请回到题面查看. Data Range 本部分和 Solution 部分变量的含义同题面. \(1\leqslant n,m\leqslant 100,0\l ...
- 2016.11.6 night NOIP模拟赛 考试整理
题目+数据:链接:http://pan.baidu.com/s/1hssN8GG 密码:bjw8总结: 总分:300分,仅仅拿了120份. 这次所犯的失误:对于2,3题目,我刚刚看就想到了正确思路,急 ...
- 2016.10.29 NOIP模拟赛 PM 考试整理
300分的题,只得了第三题的100分. 题目+数据:链接:http://pan.baidu.com/s/1o7P4YXs 密码:4how T1:这道题目存在着诸多的问题: 1.开始的序列是无法消除的( ...
随机推荐
- 手动设计神经网络进行MNIST分类
前言: 用手工设计的两层神经网络,经过200个epoch,最后得到0.9599,约0.96的精度 正文 import tensorflow as tf from tensorflow.examples ...
- MSSQL注入--反弹注入
明明是sql注入的点,却无法进行注入,注射工具拆解的速度异常的缓慢,错误提示信息关闭,无法返回注入的结果,这个时候你便可以尝试使用反弹注入, 反弹注入需要依赖于函数opendatasource的支持, ...
- Node.js实战1:创建一个新的Node项目。
你也许在猜专业的Node开发如何创建一个新项目. 有Npm在 ,这会非常简单. 虽然你可以创建一个JS文件,并执行:node file.js,但我建议你使用npm init来先创建一个node项目,这 ...
- Python 内置函数super
super()函数是用于调用父类/超类的一个方法 super是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没有问题,但是如果使用多继承,会涉及到查找顺序(MRO),重复调用(钻石继 ...
- TortoiseGit不用每次输入用户名和密码的方法
TortoiseGit每次同步代码时,都会让输入用户名和密码,虽然安全,但是自己用有点麻烦. 怎么解决呢?废话不多说,直接上图: 1.设置—编辑本地.git/config 2.在本地.git/conf ...
- android adb logcat获取日志文件
一般情况,可以直接在电脑终端上输入logcat来查看手机运行日志,但是测试工作者为了抓取日志文件来给开发人员,需要把日志导出到特定文件中.如下文. 以小米1s手机为例 步骤1:打开第一个终端窗口 ad ...
- 类———用类定义对象———error:C++表达式必须包含类类型
//原文参考https://blog.csdn.net/lanchunhui/article/details/52503332 你以为你定义了一个类的对象,其实在编译器看来你是声明了一个函数 clas ...
- 洛谷 P1541 乌龟棋 & [NOIP2010提高组](dp)
传送门 解题思路 一道裸的dp. 用dp[i][j][k][kk]表示用i个1步,j个2步,k个3步,kk个4步所获得的最大价值,然后状态转移方程就要分情况讨论了(详见代码) 然后就是一开始统计一下几 ...
- Neo4j清空所有数据
两种方法: 一.用下列 Cypher 语句: match (n) detach delete n 二. 1.停掉服务: 2.删除 graph.db 目录: 3.重启服务. 原文地址:http://ne ...
- 逆向与反汇编实战(一)--PEiD分析复现
1.准备 简介: PEiD(PE Identifier)是一款著名的查壳工具,其功能强大,几乎可以侦测出所有的壳,其数量已超过470 种PE 文档 的加壳类型和签名. 整个过程需要测试文件成品:htt ...