AtCoder Regular Contest 093
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的更多相关文章
- Atcoder Regular Contest 093 D - Dark Horse(组合数学+状压 dp)
Atcoder 题面传送门 & 洛谷题面传送门 常规题,简单写写罢((( 首先 \(1\) 的位置是什么不重要,我们不妨钦定 \(1\) 号选手最初就处在 \(1\) 号位置,最后答案乘个 \ ...
- AtCoder Regular Contest 093 E: Bichrome Spanning Tree(生成树)
Bichrome Spanning Tree 题意: 给出一个n个点,m条边的无向连通图,现在要给每条边染色,可以染成黑色或者白色. 现在要求在染色完毕后,找出一个至少包含一条黑边和一条白边的最小生成 ...
- AtCoder Regular Contest 061
AtCoder Regular Contest 061 C.Many Formulas 题意 给长度不超过\(10\)且由\(0\)到\(9\)数字组成的串S. 可以在两数字间放\(+\)号. 求所有 ...
- AtCoder Regular Contest 094 (ARC094) CDE题解
原文链接http://www.cnblogs.com/zhouzhendong/p/8735114.html $AtCoder\ Regular\ Contest\ 094(ARC094)\ CDE$ ...
- AtCoder Regular Contest 092
AtCoder Regular Contest 092 C - 2D Plane 2N Points 题意: 二维平面上给了\(2N\)个点,其中\(N\)个是\(A\)类点,\(N\)个是\(B\) ...
- AtCoder Regular Contest 094
AtCoder Regular Contest 094 C - Same Integers 题意: 给定\(a,b,c\)三个数,可以进行两个操作:1.把一个数+2:2.把任意两个数+1.求最少需要几 ...
- AtCoder Regular Contest 095
AtCoder Regular Contest 095 C - Many Medians 题意: 给出n个数,求出去掉第i个数之后所有数的中位数,保证n是偶数. \(n\le 200000\) 分析: ...
- AtCoder Regular Contest 102
AtCoder Regular Contest 102 C - Triangular Relationship 题意: 给出n,k求有多少个不大于n的三元组,使其中两两数字的和都是k的倍数,数字可以重 ...
- AtCoder Regular Contest 096
AtCoder Regular Contest 096 C - Many Medians 题意: 有A,B两种匹萨和三种购买方案,买一个A,买一个B,买半个A和半个B,花费分别为a,b,c. 求买X个 ...
随机推荐
- A1261. happiness(吴确)[二元组暴力最小割建模]
A1261. happiness(吴确) 时间限制:500ms 内存限制:512.0MB 总提交次数:158 AC次数:72 平均分:56.71 将本题分享到: 查看 ...
- 160719、Spring + Dubbo + zookeeper (linux) 框架搭建
转载一篇博客,写得不错(至少我参考一下搭建成功了) 转载地址:http://my.oschina.net/wangt10/blog/522799 dubbo简介 节点角色说明: Provider: 暴 ...
- Java日期类:Date和Calendar的使用
总是使用这两个类,总是需要百度.还不如一次全部整理完. 一.介绍: Date 类 Date 表示特定的瞬间,精确到毫秒. 在 JDK 1.1 之前,类 Date 有两个其他的函数.它允许把日期解释为年 ...
- Xenu Link Sleuth
Xenu Link Sleuth 是一款检查网站死链接的软件,可以通过它打开一个本地的网页文件来检查它的链接,也可以输入任何网址来检查. 具体使用如下: 1,下载,并安装. 2,打开软件,出现 Tip ...
- 解决Object() takes on paramenters的问题
先贴上今天的代码: 解决:是由于父类中的_init_()写成了_int_(),由于粗心导致,下次注意.
- Tflearn的安装
scipy-doc安装 sudo apt-get install python-scipy-doc安装python-scipy-doc h5py安装 sudo pip install h5py sci ...
- js 实现无限加载分页(适合移动端)
一.原理:当滚动条到达底部时,执行下一页内容. 判断条件需要理解三个概念: 1.scrollHeight 真实内容的高度 2.clientHeight 视窗的高度,即在浏览器中所能看到的内 ...
- Centos学习笔记2-网络部分
一:修改IP地址:vi /etc/sysconfig/network-scripts/ifcfg-eth0 IPADDR=192.168.80.100 NETMASK=255.255.255.0 GA ...
- redis实现队列queue
参考:<Redis入门指南>第4章进阶 http://book.51cto.com/art/201305/395461.htm 4.4.2 使用Redis实现任务队列 说到队列很自然就能想 ...
- [转]Asp.net MVC 中Ajax的使用
Asp.net MVC 抛弃了Asp.net WebForm那种高度封装的控件,让我们跟底层的HTML有了更多的亲近.可以更自由.更灵活的去控制HTML的结构.样式和行为.而这点对于Ajax的应有来说 ...