T1 jkl

题解

显然每次都取a[i]的最大值/最小值,并更新a[i]即可

用数据结构维护这一操作。。得分看常数

事实上用v[i]记录权值为i的个数,然后for乱搞就可以了。。。

其它乱搞做法能获得不同的分数

提供一种50分解法

排序后

最小值,从左依次取到0

最大值,一直取最右的那个,如果它变得比前面的小就交换位置。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int n,m;
int a[1000005],t[1000005];
long long mn,mx;
int main()
{
m=read();n=read();
for(int i=1;i<=m;i++)a[i]=read();
sort(a+1,a+m+1);
for(int i=1;i<=m;i++)t[i]=a[i];
int now=1;
for(int i=1;i<=n;i++)
{
mn+=t[now];
t[now]--;if(!t[now])now++;
}
for(int i=1;i<=m;i++)
t[i]=a[i];
for(int i=1;i<=n;i++)
{
mx+=t[m];
t[m]--;
int k=m;
while(t[k]<t[k-1])swap(t[k],t[k-1]),k--;
}
printf("%lld %lld",mx,mn);
return 0;
}

AC做法

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#define ll long long
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int n,m;
int a[1000005];
priority_queue<int> q;
ll mx,mn;
int main()
{
n=read();m=read();
for(int i=1;i<=n;i++)a[i]=read(),q.push(a[i]);
sort(a+1,a+n+1);
int now=1;
for(int i=1;i<=m;i++)
{
int t=q.top();q.pop();
mx+=t;
q.push(t-1);
while(!a[now])now++;
mn+=a[now];a[now]--;
}
printf("%lld %lld",mx,mn);
return 0;
}

T2 walk

题解

第一种做法直接暴力找循环节。。。

可以得70分

正解裸倍增

\(f[k,i]\)代表从i开始走2^k步会到哪里,初始\(f[0,i]=next[i]\)

\(f[k,i]=f[k-1,f[k-1,i]]\),复杂度\(m*log(n)\)

暴力(我的代码)

#include<bits/stdc++.h>
using namespace std; inline long long read()
{
long long x = 0,t = 1; char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-') t = -1; ch = getchar();}
while(ch >= '0' && ch <= '9'){x = x*10 + ch -'0'; ch = getchar();}
return x*t;
} int n,m,num[100010]; inline void init()
{
n = read(); m = read();
for(int i = 1;i <= n;++i)
{
num[i] = read();
}
} inline void greed()
{
for(int i = 1;i <= m;++i)
{
int t = read();
long long k = read();
int end,cnt=0;
int vis[100010]; for(int i=1;i<=n;i++)vis[i]=0; for(int i=t;!vis[i];i=num[i])
{
vis[i]=1;
end=num[i];
} while(k&&t!=end)t=num[t],k--; if(k)
{
cnt=1;
while(num[end]!=t) cnt++,end=num[end];
k%=cnt;
}
while(k--)t=num[t]; printf("%d\n",t);
}
} int main(int argc, char const *argv[])
{
init();
greed();
return 0;
}

AC做法

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<vector>
#define ll long long
using namespace std;
inline ll read()
{
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
ll bin[65];
int n,m;
int to[100005][65];
int main()
{
n=read();m=read();
bin[0]=1;for(int i=1;i<=60;i++)bin[i]=bin[i-1]<<1;
for(int i=1;i<=n;i++)to[i][0]=read();
for(int i=1;i<=60;i++)
for(int j=1;j<=n;j++)
to[j][i]=to[to[j][i-1]][i-1];
for(int i=1;i<=m;i++)
{
int x=read();ll k=read();
for(int t=0;t<=60;t++)if(k&bin[t])x=to[x][t];
printf("%d\n",x);
}
return 0;
}

T3 mokou

题解

题目大意

给定一个无向有权图,首先一个最小生成树 MST,从 MST 中选取一个度数大于 1 的点 作为根 K,使每颗子树及该子树到根的边权之和方差最小。输出 K 和最小方差的值。

考察算法最小生成树 树的遍历

算法1

首先毫无疑问的需要用到求最小生成树的算法,我们考虑使用 Kruskal 算法或是Prim 算法。求出最小生成树以后,依次枚举每一个点作为根进行遍历,取出其中的最小方差即可。

时间复杂度:\(O(MlogM+N^2)\)

期望得分:60

算法2

由于后 40%的数据 N 比较大,所以只能通过 Kruskal 算法求出最小生成树,接下来任选一个点作为根,进行一次遍历。记录 w[i]表示以 i 点作为根的子树的边权之和。 然后依次枚举每一个点 i,该点的子树权值可以直接求出,而以它父亲作为根的子树需要特殊处理。这颗特殊子树的权值为最小生成树总权值减去该点权值 w[i]。然后计算出方差,最后选取所有点当中最小方差的那个点即可。

时间复杂度:\(O(MlogM+N)\)

期望得分:100

暴力

#include <iostream>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
using namespace std; #define MAXN 50009
#define MAXE 200009
#define pb(x) push_back(x)
#define mk(x, y) make_pair(x, y) struct EDGE
{
int u, v;
double length;
} edge[ MAXE ];
int N, edgecnt; struct Tree
{
vector< pair<int, double> > fir[ MAXN ];
double Sum, w[ MAXN ];
bool vis[ MAXN ]; void Addedge(int u, int v, double length)
{
Sum += length;
fir[u].pb( mk(v, length) );
fir[v].pb( mk(u, length) );
return ;
} void DFS(int now)
{
vis[ now ] = true;
w[ now ] = 0;
for (int i = 0; i != fir[now].size(); i++)
if (!vis[ fir[now][i].first ])
{
DFS( fir[now][i].first );
w[now] += fir[now][i].second + w[ fir[now][i].first ];
}
return ;
} void GetAns()
{
int best(-1);
double best_ans(0), tp(0), Avg(0);
for (int i = 1; i <= N; i++)
if (fir[i].size() > 1)
{
memset(vis, 0, sizeof(vis));
DFS(i);
tp = 0;
Avg = Sum / fir[i].size();
for (int j = 0; j != fir[i].size(); j++)
tp += (Avg - fir[i][j].second - w[ fir[i][j].first ]) * (Avg - fir[i][j].second - w[ fir[i][j].first ]);
if (best == -1 || tp < best_ans)
best_ans = tp, best = i;
}
printf("%d\n", best);
return ;
}
} MST; struct Kruskal
{
int path[ MAXN ]; int Find(int x)
{
if (x != path[x]) path[x] = Find( path[x] );
return path[x];
} void Input()
{
scanf("%d %d", &N, &edgecnt);
for (int i = 1; i <= edgecnt; i++)
scanf("%d %d %lf", &edge[i].u, &edge[i].v, &edge[i].length);
return ;
} void Work()
{
int cnt(1), x, y;
for (int i = 1; i <= N; i++)
path[i] = i;
for (int i = 1; i <= edgecnt && cnt < N; i++)
{
x = Find( edge[i].u );
y = Find( edge[i].v );
if (path[x] == path[y]) continue;
path[x] = path[y];
MST.Addedge(edge[i].u, edge[i].v, edge[i].length);
++cnt;
}
return ;
}
} Kruskal; bool Comp(EDGE x, EDGE y)
{
return x.length < y.length;
} int main()
{ Kruskal.Input();
sort(edge + 1, edge + edgecnt + 1, Comp);
Kruskal.Work();
MST.GetAns(); return 0;
}

AC做法

#include <iostream>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
using namespace std; #define MAXN 50009
#define MAXE 200009
#define pb(x) push_back(x)
#define mk(x, y) make_pair(x, y) struct EDGE
{
int u, v;
double length;
} edge[ MAXE ];
int N, edgecnt; struct Tree
{
vector< pair<int, double> > fir[ MAXN ];
double Sum, w[ MAXN ];
int path[ MAXN ];
bool vis[ MAXN ]; void Addedge(int u, int v, double length)
{
Sum += length;
fir[u].pb( mk(v, length) );
fir[v].pb( mk(u, length) );
return ;
} void DFS(int now)
{
vis[ now ] = true;
for (int i = 0; i != fir[now].size(); i++)
if (!vis[ fir[now][i].first ])
{
path[ fir[now][i].first ] = now;
DFS( fir[now][i].first );
w[now] += fir[now][i].second + w[ fir[now][i].first ];
}
return ;
} void GetAns()
{
int best(-1);
double best_ans(0), tp(0), Avg(0);
DFS(1);
for (int i = 1; i <= N; i++)
if (fir[i].size() > 1)
{
tp = 0;
Avg = Sum / fir[i].size();
for (int j = 0; j != fir[i].size(); j++)
if (fir[i][j].first != path[i])
tp += (Avg - fir[i][j].second - w[ fir[i][j].first ]) * (Avg - fir[i][j].second - w[ fir[i][j].first ]);
else tp += (Avg - (Sum - w[i])) * (Avg - (Sum - w[i]));
if (best == -1 || tp < best_ans)
best_ans = tp, best = i;
}
printf("%d\n", best);
return ;
}
} MST; struct Kruskal
{
int path[ MAXN ]; int Find(int x)
{
if (x != path[x]) path[x] = Find( path[x] );
return path[x];
} void Input()
{
scanf("%d %d", &N, &edgecnt);
for (int i = 1; i <= edgecnt; i++)
scanf("%d %d %lf", &edge[i].u, &edge[i].v, &edge[i].length);
return ;
} void Work()
{
int cnt(1), x, y;
for (int i = 1; i <= N; i++)
path[i] = i;
for (int i = 1; i <= edgecnt && cnt < N; i++)
{
x = Find( edge[i].u );
y = Find( edge[i].v );
if (path[x] == path[y]) continue;
path[x] = path[y];
MST.Addedge(edge[i].u, edge[i].v, edge[i].length);
++cnt;
}
return ;
}
} Kruskal; bool Comp(EDGE x, EDGE y)
{
return x.length < y.length;
} int main()
{ Kruskal.Input();
sort(edge + 1, edge + edgecnt + 1, Comp);
Kruskal.Work();
MST.GetAns(); return 0;
}

18年10月30日 NOIP模拟赛的更多相关文章

  1. 18年10月31日 NOIP模拟赛

    T1.exercise 题解 数据很小直接模拟 代码 #include<iostream> #include<cstdio> #include<cmath> #in ...

  2. 18年11月5日 NOIP模拟赛

    T1 题解 对于k=100的情况,贪心 对于100%的数据 可以发现,当前的决策只对后面的开采有影响,且剩余耐久度与之后的开采收益成正比,如果倒着考虑这个问题,得出i-n的星球1点耐久度所能获得的最大 ...

  3. 9月24日noip模拟赛解题报告

    1.校门外的树(tree.c/cpp/pas 128M,1s) Description LSGJ扩建了,于是校门外有了一条长为L的路.路上种了一排的树,每相邻两棵树之间的距离为1,我们可以把马路看成一 ...

  4. 2016年10月30日 星期日 --出埃及记 Exodus 19:15

    2016年10月30日 星期日 --出埃及记 Exodus 19:15 Then he said to the people, "Prepare yourselves for the thi ...

  5. 10 月 30 日新款 Mac mini 有望与新款 iPad Pro 一起发布

    苹果最新款的 Mac mini 是在 2014 年 10 月推出的版本,到现在已经过了 4 年.分析师郭明錤和彭博社的 Mark Gurman 都表示苹果会在今年晚些时候发布新款 Mac mini. ...

  6. 10 月 30 日 北京 LiveVideoStack 阿里云视频云专场限量赠票 100 张

    10 月 30 日 | 北京 LiveVideoStack 将携手阿里云共邀 4 位技术大咖,一同探讨从上云到创新,视频云的新技术与新场景.阿里云视频云依托阿里云服务数百万开发者的卓越服务能力与实践, ...

  7. NOIP2017赛前模拟10月30日总结

    题目1: n个人参赛(n<=100000),每个人有一个权值··已知两个人权值绝对值之差小于等于K时,两个人都有可能赢,若大于则权值大的人赢···比赛为淘汰制,进行n-1轮·问最后可能赢的人有多 ...

  8. 10月30日下午 PHP精确查询(模糊查询、模糊+关键字共同查询)

    1.一个条件的模糊查询 <body> <br /> <form action="main.php" method="post"&g ...

  9. 10月30日上午MySQL数据库的修改(从网页上实现对数据库的更改)

    从网页页面上对数据库进行更改,连接着之前做的增加.删除.查询. 1.先做一个修改页面 <body> <!--这个页面需要让用户看到一些数据,所以不是一个纯php页面,页面效果和增加页 ...

随机推荐

  1. c#中引用类型作为值参数和引用参数问题

    一.分类 C#的值类型包括:结构体(数值类型,bool型,用户定义的结构体),枚举,可空类型. C#的引用类型包括:数组,用户定义的类.接口.委托,object,字符串. 二.参数传递 对于引用类型, ...

  2. 细说setTimeout/setImmediate/process.nextTick的区别

    node.js中的非IO的异步API提供了四种方法,分别为setTimeOut(),setInterval(),setImmediate()以及process.nextTick(),四种方法实现原理相 ...

  3. 15.Generator 函数的语法

    Generator 函数的语法 Generator 函数的语法 简介 基本概念 Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同.本章详细介绍 Generat ...

  4. Vertica示例数据库安装

    1.示例数据库简介: Vertica跟传统数据库一样,自带了示例数据库--VMart示例数据库,是一个多架构数据库.该数据是大型超市(VMart)中可能会用到的数据库,可用来访问产品.客户.员工以及网 ...

  5. spring定时任务(@Scheduled注解)

    (一)在xml里加入task的命名空间 xmlns:task="http://www.springframework.org/schema/task" http://www.spr ...

  6. 我用ASP.NET缓存之SQL数据缓存依赖(SqlCacheDependency)

    [名词解释] 缓存(Cache)依赖,大白话解释就是缓存是否更新依赖于其它Object.那么SqlCacheDependency指的就是Cache的数据更新依赖于SQL Server数据库表的变化(  ...

  7. ibatis中$和#的区别

    比如当变量name的类型是Stirng时, $name$ 打印出来的是 张三 #name# 打印出来的是 ‘张三’ $ 的作用实际上是字符串拼接 #用于变量替换 那什么时候用$,什么时候 用 # (1 ...

  8. future3.2 Tomcat启动时错误:Cannot rename original file to ...

    其日志中第一个警告如下: 警告: Unexpected exception resolving reference java.io.IOException: Cannot rename origina ...

  9. vue-quill-editor 富文本集成quill-image-extend-module插件实例,以及UglifyJsPlugin打包抱错问题处理

    官网 vue-quill-editor Toolbar Module - Quill vue-quill-image-upload 图片支持上传服务器并调整大小 1.在 package.json 中加 ...

  10. WinForm中使用CrystalReport水晶报表——基础,分组统计,自定义数据源

    开篇 本篇文章主要是帮助刚开始接触CrystalReport报表的新手提供一个循序渐进的教程.该教程主要分为三个部分1)CrystalReport的基本使用方法:2)使用CrystalReport对数 ...