AtCoder Regular Contest 093


C - Traveling Plan

题意:

给定n个点,求出删去i号点时,按顺序从起点到一号点走到n号点最后回到起点所走的路程是多少。

\(n\le 2e5\)

分析:

可以通过观察发现,无论删去那个点,比全部都走所差距的距离都是\(|a_i-a_{i-1}|-|a_{i+1}-a_i|+|a_{i-1}-a_{i+1}|\)

所以直接枚举即可。

#include <bits/stdc++.h>
using namespace std;
const int MAXN=1e5+7;
int a[MAXN],n,ans;
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n+1;i++) ans+=abs(a[i]-a[i-1]);
for(int i=1;i<=n;i++){
cout<<ans-abs(a[i]-a[i-1])-abs(a[i]-a[i+1])+abs(a[i-1]-a[i+1])<<endl;
}
}

D - Grid Components

题意:

求一个边长均小于等于100的矩阵,涂成黑白两色,使得白色连通块和黑色连通块的数量分别是A、B。输出这个矩阵的长宽,并输出这个矩阵的具体涂色方案('.'是白色,'#'是黑色)。

\(1\le A,B \le 500\)

分析:

经过观察发现100×100的矩阵一定可以满足所有要求。

那么这么构造,首先把上下两部分平分开,上面是白色下面是黑色,然后一个一个的在白色里填充黑色,黑色同理。

填充方法是从头开始每隔一行一列就填一个,可以证明这样填上下两个矩阵每个矩阵都可以填600个以上所以可以轻松满足要求。

#include <bits/stdc++.h>
using namespace std;
int a,b;
char ch[201][201];
int main()
{
for(int i=1;i<=50;i++)
for(int j=1;j<=100;j++)
ch[i][j]='.';
for(int i=51;i<=100;i++)
for(int j=1;j<=100;j++)
ch[i][j]='#';
cin>>a>>b;
a--;b--;
int cnt1=0,cnt2=0;
for(int i=1;i<=50;i+=2){
if(cnt1==b) break;
for(int j=1;j<=100;j+=2){
if(cnt1==b) break;
cnt1++;
ch[i][j]='#';
}
}
for(int i=52;i<=100;i+=2){
if(cnt2==a) break;
for(int j=1;j<=100;j+=2){
if(cnt2==a) break;
cnt2++;
ch[i][j]='.';
}
}
cout<<"100 100"<<endl;
for(int i=1;i<=100;i++){
for(int j=1;j<=100;j++){
cout<<ch[i][j];
}
cout<<endl;
}
}

E - Bichrome Spanning Tree

题意:

给出一个N个点M条边的无向图,现在要给一些边染黑色或者白色,现在从这些边中选出一些边生成若干棵生成树,要求这些生成树至少包含一条白色的边和一条黑色的边,而且这些生成树的最小值是X,问有多少种染色方法。

分析:

先求一下最小生成树并且设其权值和为s。

那么分情况讨论一下,对于\(s>x\) 的情况,明显答案是0;

对于\(s=x\)的情况,我们可以确定求得那棵树一定是这个最小生成树,所以记录一下所有在最小生成树中的边。那么这些边之外的边就可以随意染色,然后保证最小生成树中的边不是全黑或者全白就可以了。容易得出答案是\(2^{M-m}\times(2^m-1)\)种。

首先必须把S里面的的所有边涂成黑色(或者白色),先假设全部涂成黑色,那么剩余的边,对每一条边单独处理,对边e,它染成白色添加进去之后,如果和集合S中的边形成的满足题意的最小生成树权重w′小于X,那么这条边只能继续涂成黑色;如果w′大于X,它涂成黑色白色都无所谓;然后把w′等于X的边的数量统计下来,假设有tot条边,可以知道这tot条边只要有一条边是白色就行了,因为只要选中这里面的一条边,剩余的边肯定都是从集合S中选出来了, 不可能再从其它边中选取,如果必须涂成黑色的有d条边, 那么答案就是2M−tot−d∗(2tot−1),最终结果再乘以2就行了,就是必须涂成一种颜色的有两种涂法

(借鉴自:AtCoder Regular Contest 093(E-Bichrome Spanning Tree)

#include <bits/stdc++.h>
using namespace std;
const int MAXN=2010;
#define ll long long
#define int ll
const int mo=1e9+7;
struct po
{
int x,y,l;
}a[MAXN];
bool cmp(po a,po b){return a.l<b.l;}
int n,m,tmp,x;
int f[MAXN];
int find(int x) {return x==f[x]?x:f[x]=find(f[x]);}
int kruskal(int now)
{
int res=0;
for(int i=1;i<=n;i++) f[i]=i;
if(now) {res+=a[now].l;f[a[now].x]=a[now].y;}
for(int i=1;i<=m;i++){
int r1=find(a[i].x),r2=find(a[i].y);
if(r1==r2) continue;
res+=a[i].l;
f[r1]=r2;
}
return res;
}
inline int power(int x,int k)
{
int cnt=1;
while(k){
if(k&1) cnt=cnt*x%mo;
k>>=1;
x=x*x%mo;
}
return cnt;
}
int val,cnt1,cnt2;
int ans;
main()
{
cin>>n>>m>>x;
for(int i=1;i<=m;i++) cin>>a[i].x>>a[i].y>>a[i].l;
sort(a+1,a+m+1,cmp);
tmp=kruskal(0);
if(tmp>x){
cout<<0;
return 0;
}
if(tmp==x){
for(int i=1;i<=m;i++){
val=kruskal(i);
if(val==x) cnt1++;
else cnt2++;
}
ans=((power(2,cnt1)-2)*power(2,cnt2)%mo+mo)%mo;
} else {
for(int i=1;i<=m;i++){
val=kruskal(i);
if(val==x) cnt1++;
else if(val>x) cnt2++;
}
ans=(2*(power(2,cnt1)-1)%mo*power(2,cnt2)%mo+mo)%mo;
}
cout<<ans;
}

F - Dark Horse

题意:

有2N个选手参与一场比赛,比赛规则是:相邻的两个人比赛一次,败者淘汰掉,胜者继续进行,直到只剩一个人为止。现在给出1号选手会败给哪些选手并且已知其他选手之间均满足:两个选手比赛,编号小的一定会胜利。现在可以安排每个选手初始的位置,要钦定1号选手最后获胜,求能满足条件的初始位置的方案数。

分析:

由于可以明显发现1号无论站在哪里最后的胜负方案数都是一样的,所以可以直接就让1号在一号位置,然后将答案最后乘上\(2^n\)即可。

考虑1号一定会打n场,而且每次都会和\(2^n+1...2^{n+1}\)中编号最小的人打,所以保证其中没有人在ad这个集合内就可以了。

以下部分摘自dalao:

接下来就是本题最有趣的地方了:容斥原理。

设S为N个块的一个子集,\(f(S)\)表示这个子集中所有块的最小值均在A的范围内(其余块是否在A的范围内不考虑)的方案数。

这样一来,最终答案即为\(∑(−1)^{|S|}f(S)\)

将A从大到小排序,依次考虑加入\(A_i\)后的\(f(S)\)。

1、成为一个块的最小值:那么在这个块中,必须填充相应数量的,编号比AiAi大的选手,组合数统计。

2、不成为块的最小值,不操作即可\((dp[i][S]+=dp[i−1][S])\)。

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define int ll
const int MAXN=20;
const int MAXM=2<<16+1;
const int mo=1e9+7;
int n,m,a[MAXN],bit[MAXN],c[MAXM];
int fac[MAXM],inv[MAXM],dp[MAXN][MAXM];
int power(int x,int k)
{
int cnt=1;
while(k){
if(k&1) cnt=cnt*x%mo;
x=x*x%mo;
k>>=1;
}
return cnt;
}
int C(int x,int y){return 1ll*fac[x]*inv[y]%mo*inv[x-y]%mo;}
main()
{
cin>>n>>m;
for(int i=1;i<=m;i++) cin>>a[i];
reverse(a+1,a+m+1);
for(int i=0;i<=n-1;i++) bit[i]=1<<i;
int cnt=1<<n;fac[0]=1;
for(int i=1;i<=cnt;i++)
fac[i]=1ll*fac[i-1]*i%mo;
inv[cnt]=power(fac[cnt],mo-2);
for(int i=cnt-1;i>=0;i--)
inv[i]=inv[i+1]*(i+1ll)%mo;
int u=(1<<n)-1;dp[0][0]=1;
for(int i=1;i<=m;i++)
for(int s=0;s<=u;s++){
int l=cnt-a[i]+1-s;
dp[i][s]=(dp[i][s]+dp[i-1][s])%mo;
for(int j=0;j<=n-1;j++){
if(l<bit[j]) break;
if(bit[j]&s) continue;
dp[i][s^bit[j]]=(dp[i][s^bit[j]]+(1ll*dp[i-1][s]*C(l-1,bit[j]-1))%mo*fac[bit[j]]%mo)%mo;
}
}
int ans=fac[cnt-1]; c[0]=1;
for(int s=1;s<=u;s++){
c[s]=-c[s-(s&-s)];
ans=(ans+1ll*c[s]*dp[m][s]*fac[cnt-1-s]%mo)%mo;
}
ans=(1ll*ans*cnt%mo+mo)%mo;
cout<<ans;
}

AtCoder Regular Contest 093的更多相关文章

  1. Atcoder Regular Contest 093 D - Dark Horse(组合数学+状压 dp)

    Atcoder 题面传送门 & 洛谷题面传送门 常规题,简单写写罢((( 首先 \(1\) 的位置是什么不重要,我们不妨钦定 \(1\) 号选手最初就处在 \(1\) 号位置,最后答案乘个 \ ...

  2. AtCoder Regular Contest 093 E: Bichrome Spanning Tree(生成树)

    Bichrome Spanning Tree 题意: 给出一个n个点,m条边的无向连通图,现在要给每条边染色,可以染成黑色或者白色. 现在要求在染色完毕后,找出一个至少包含一条黑边和一条白边的最小生成 ...

  3. AtCoder Regular Contest 061

    AtCoder Regular Contest 061 C.Many Formulas 题意 给长度不超过\(10\)且由\(0\)到\(9\)数字组成的串S. 可以在两数字间放\(+\)号. 求所有 ...

  4. AtCoder Regular Contest 094 (ARC094) CDE题解

    原文链接http://www.cnblogs.com/zhouzhendong/p/8735114.html $AtCoder\ Regular\ Contest\ 094(ARC094)\ CDE$ ...

  5. AtCoder Regular Contest 092

    AtCoder Regular Contest 092 C - 2D Plane 2N Points 题意: 二维平面上给了\(2N\)个点,其中\(N\)个是\(A\)类点,\(N\)个是\(B\) ...

  6. AtCoder Regular Contest 094

    AtCoder Regular Contest 094 C - Same Integers 题意: 给定\(a,b,c\)三个数,可以进行两个操作:1.把一个数+2:2.把任意两个数+1.求最少需要几 ...

  7. AtCoder Regular Contest 095

    AtCoder Regular Contest 095 C - Many Medians 题意: 给出n个数,求出去掉第i个数之后所有数的中位数,保证n是偶数. \(n\le 200000\) 分析: ...

  8. AtCoder Regular Contest 102

    AtCoder Regular Contest 102 C - Triangular Relationship 题意: 给出n,k求有多少个不大于n的三元组,使其中两两数字的和都是k的倍数,数字可以重 ...

  9. AtCoder Regular Contest 096

    AtCoder Regular Contest 096 C - Many Medians 题意: 有A,B两种匹萨和三种购买方案,买一个A,买一个B,买半个A和半个B,花费分别为a,b,c. 求买X个 ...

随机推荐

  1. JMeter java.net.URISyntaxException: Illegal character in query at index

    请求参数未编码,会造成请求解析失败.把编码勾上,就可以了.

  2. java注解类定时器

    package com.jianwu.task; import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONObject;imp ...

  3. JRE not compatible with workspace .class file compatibility: 1.7

    在进行Eclipse开发的时候,经常会遇到一些小问题,现在开始每天积累一些小问题的解决方法.出现:JRE not compatible with workspace .class file compa ...

  4. jQuery与Zepto

    jQuery和Zepto是我比较常用的插件.其实用法差不太多,可以说Zepto是jQuery的轻量级替代品,但是不要认为Zepto就没有jQuery好用,因为Zepto有jQuery没有的功能,就是移 ...

  5. IDEA 设置代码模板

    一.代码模板 参考: IntelliJ IDEA 使用(一)基本设置与类.方法模板设置 - 云 + 社区 - 腾讯云 文件代码模板的使用 - IntelliJ IDEA 使用教程 - 极客学院 Wik ...

  6. bootstrap3.3.6 CDN

    <!-- Latest compiled and minified CSS --> <link rel="stylesheet" href="//max ...

  7. IO流入门-第十章-DataInputStream_DataOutputStream

    DataInputStream和DataOutputStream基本用法和方法示例 /* java.io.DataOutputStream 数据字节输出流,带着类型写入 可以将内存中的“int i = ...

  8. spring 攻略

    1.5 指定Bean引用 为了Bean之间相互访问,在Bean配置文件中通过<ref>元素为Bean属性或构造程序参数指定Bean引用. <property name="p ...

  9. 修改hosts文件不起作用

    今天遇到个很奇怪的问题,在hosts文件里添加了一些域名指向后,发现根本没起作用,后来还发现个细节,就是hosts文件左下角有个小锁的标志,开始以为是杀毒软件之类的把他锁了.可是没找到在哪里有相关操作 ...

  10. python列表套字典数据类型转换

    1.题目 list3 = [ {'name':'Alex','hobby':'抽烟'}, {'name':'Alex', 'hobby':'喝酒'}, {'name':'Alex', 'hobby': ...