[Atcoder SHPC2018] Tutorial
Link:
C:
一道看上去有些吓人的题目,不过$1e9$规模下的$n^m$代表肯定是可以约分的
可以发现能提供贡献的数对只有$2*(n-d)$种,那么总贡献为$2*(n-d)*(m-1)*n^{m-2}$
除去$n^m$后就是$\frac{2*(n-d)*(m-1)}{n^2}$($d=0$时要特殊处理)
#include <bits/stdc++.h> using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> P;
ld n,m,d;
int main()
{
scanf("%Lf%Lf%Lf",&n,&m,&d);
printf("%.10Lf",(n-d)*(m-)/(n*n)*(d?2.0:1.0));
return ;
}
Problem C
一般此类难以枚举所有状态的题目都是利用计算每种可能答案的贡献来解决
D:
发现了自己英语渣渣的本质……
把$some day$理解为$some days$就觉得不可做了,以后还是要学好英语注意单复数啊……
如果只能转换一次就非常容易了:
分别从起点和终点根据不同边权跑最短路,算出在每个点转换时的最小代价
从后往前取$min$就能找到在前$i$个点不能转换时的最小代价了
#include <bits/stdc++.h> using namespace std;
#define X first
#define Y second
typedef long long ll;
typedef pair<ll,ll> P;
const int MAXN=1e5+;
int n,m,S,T,x,y,a,b;
ll res[MAXN],INF=1e15,d1[MAXN],d2[MAXN];
vector<P> G1[MAXN],G2[MAXN]; void dijkastra(vector<P> *G,ll *d,int start)
{
priority_queue<P,vector<P>,greater<P> > q;
for(int i=;i<MAXN;i++) d[i]=INF;
q.push(P(,start));d[start]=;
while(!q.empty())
{
P t=q.top();q.pop();
int u=t.Y;ll cost=t.X;
if(cost>d[u]) continue;
for(int i=;i<G[u].size();i++)
{
int v=G[u][i].X;
if(d[v]>d[u]+G[u][i].Y)
d[v]=d[u]+G[u][i].Y,q.push(P(d[v],v));
}
}
} int main()
{
scanf("%d%d%d%d",&n,&m,&S,&T);
for(int i=;i<=m;i++)
scanf("%d%d%d%d",&x,&y,&a,&b),
G1[x].push_back(P(y,a)),G1[y].push_back(P(x,a)),
G2[x].push_back(P(y,b)),G2[y].push_back(P(x,b)); dijkastra(G1,d1,S);dijkastra(G2,d2,T);
for(int i=;i<=n;i++) res[i]=d1[i]+d2[i];
for(int i=n-;i>=;i--) res[i]=min(res[i],res[i+]);
for(int i=;i<=n;i++) printf("%lld\n",INF-res[i]);
return ;
}
Problem D
E:
首先要意识到:如果一个点确定,其它所有点都能确定(除非有矛盾)
因此我们只要判断第一个点有多少种取值可行就能算出总的方案数
如果点$i$与起点相距偶数条边时$a_i=t+a_1$,相距奇数条边时$a_i=t-a_1$($t$为常数)
又由于要求$a_i$为正整数,我们根据$a_i\ge 0$的约束条件不断缩减$a_1$的范围即可
(需要注意,如果出现环时要么不可行要么确定唯一的$a_1$)
实现时只要写一个$dfs$即可,不断推导当前的$t$和$a_1$前的正/负号
#include <bits/stdc++.h> using namespace std;
typedef long long ll;
const int MAXN=1e5+;
struct edge{int nxt,to,w;}e[MAXN<<];
ll l=,r=1ll<<,dif[MAXN],fst=;//有可能爆2e9
int n,m,x,y,z,head[MAXN],mk[MAXN],vis[MAXN],tot=; void add(int from,int to,int w)
{e[++tot].nxt=head[from];e[tot].to=to;e[tot].w=w;head[from]=tot;} void dfs(int x,ll cur,int mark,int anc)
{
if(!vis[x])
{
mk[x]=mark;dif[x]=cur;vis[x]=;
if(fst&&dif[x]+mk[x]*fst<=)
puts(""),exit(); if(mk[x]>) l=max(l,-dif[x]+);
else r=min(r,dif[x]-);
}
else
{
if(cur==dif[x]&&mark==mk[x]) return;
if(cur!=dif[x]&&mark==mk[x])
puts(""),exit(); ll t=(dif[x]-cur)/(mark-mk[x]);
if(t*(mark-mk[x])==dif[x]-cur && ((!fst)||fst==t)) fst=t;
else puts(""),exit();
return;
}
for(int i=head[x];i;i=e[i].nxt)
if(e[i].to!=anc) dfs(e[i].to,e[i].w-cur,-mark,x);
} int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
scanf("%d%d%d",&x,&y,&z),add(x,y,z),add(y,x,z);
dfs(,,,); if(fst) printf("");
else printf("%lld",max(0ll,r-l+));
return ;
}
Problem E
一般此类对于每个点都有限制条件的题目(如BZOJ 3573),基本上都能保证确定一点就能推出全图
此时只要判断起点能有多少种取值就行了。(推导时还要再耐心些,不要一上来就觉得题目不可做)
[Atcoder SHPC2018] Tutorial的更多相关文章
- [Atcoder Grand Contest 004] Tutorial
Link: AGC004 传送门 A: …… #include <bits/stdc++.h> using namespace std; long long a,b,c; int main ...
- [Atcoder Regular Contest 060] Tutorial
Link: ARC060 传送门 C: 由于难以维护和更新平均数的值: $Average->Sum/Num$ 这样我们只要用$dp[i][j][sum]$维护前$i$个数中取$j$个,且和为$s ...
- [Atcoder Regular Contest 061] Tutorial
Link: ARC061 传送门 C: 暴力$dfs$就好了 #include <bits/stdc++.h> using namespace std; typedef long long ...
- [Atcoder Regular Contest 065] Tutorial
Link: ARC065 传送门 C: 最好采取逆序贪心,否则要多考虑好几种情况 (从前往后贪心的话不能无脑选“dreamer”,"er"可能为"erase"/ ...
- [Atcoder 080] A~D Tutorial
很好奇这周为什么只有Beginner Contest而没有Regular Contest,本来想着去30minAK的,结果1个小时了还有一道题调不出来o(╯□╰)o A:Parking 让我体验了下开 ...
- [Atcoder Regular Contest 064] Tutorial
Link: ARC064 传送门 C: 贪心+对边界的特殊处理 #include <bits/stdc++.h> using namespace std; typedef long lon ...
- [Atcoder Regular Contest 063] Tutorial
Link: ARC063 传送门 C: 将每种颜色的连续出现称为一段,寻找总段数即可 #include <bits/stdc++.h> using namespace std; ,len; ...
- [Atcoder Grand Contest 003] Tutorial
Link: AGC003 传送门 A: 判断如果一个方向有,其相反方向有没有即可 #include <bits/stdc++.h> using namespace std; ]; map& ...
- [Atcoder Regular Contest 062] Tutorial
Link: ARC 062 传送门 C: 每次判断增加a/b哪个合法即可 并不用判断两个都合法时哪个更优,因为此时两者答案必定相同 #include <bits/stdc++.h> usi ...
随机推荐
- 解析json方式之net.sf.json
前面转载了json解析的技术:fastjson,今天说下另外一种技术. 下载地址 本次使用版本:http://sourceforge.net/projects/json-lib/files/json- ...
- namesilo注册域名用来做域名邮箱
重要的话说三遍: (一定不要再国内注册域名,不要买国内的空间) (一定不要再国内注册域名,不要买国内的空间) (一定不要再国内注册域名,不要买国内的空间) 使用的是腾讯企业邮箱,有一个缺点:不支持自定 ...
- NET中IL理解(转)
.NET CLR 和 Java VM 都是堆叠式虚拟机器(Stack-Based VM),也就是說,它們的指令集(Instruction Set)都是採用堆叠运算的方式:执行时的资料都是先放在堆叠中, ...
- 【51NOD】1486 大大走格子
[算法]动态规划+组合数学 [题意]有一个h行w列的棋盘,定义一些格子为不能走的黑点,现在要求从左上角走到右下角的方案数. [题解] 大概能考虑到离散化黑点后,中间的空格子直接用组合数计算. 然后解决 ...
- viewDidLoad方法的调用顺序
https://www.evernote.com/shard/s227/sh/01307822-de66-448d-8bac-7954f01ffc64/185b44c2bf5b6e266f4bed ...
- JS高级技巧(简洁版)
高级函数 由于在JS中,所有的函数都是对象,所以使用函数指针十分简单,也是这些东西使JS函数有趣且强大 安全的类型检测 JS内置的类型检测机制并不是完全可靠的 typeof 操作符返回一个字符串,表示 ...
- 【洛谷 SP283】NAPTIME - Naptime(DP)
题目链接 先考虑如果只有一天,那么该怎么做. 设\(f[i][j][1]\)表示前\(i\)个小时睡了\(j\)个小时并且第\(j\)个小时正在睡觉时的最大体力,\(f[i][j][1]\)表示前\( ...
- bzoj 1192 二进制
原题传送门http://www.lydsy.com/JudgeOnline/problem.php?id=1192 继续刷水题,二进制思想 //By BLADEVIL var x :longint; ...
- Linux kernel中断子系统之(五):驱动申请中断API【转】
转自:http://www.wowotech.net/linux_kenrel/request_threaded_irq.html 一.前言 本文主要的议题是作为一个普通的驱动工程师,在撰写自己负责的 ...
- Oracle基础 11 约束 constraints
--主.外键约束 create table t( id int primary key); create table t1( id int references t(id)); 或者create ...