AGC 012 D - Colorful Balls
为什么atcoder都是神仙题啊qwq
首先发现如果要让 x,y 互换位置的话,要么通过他们直接换 (也就是x和y满足两种操作之一),要么间接换,通过一些其他的元素形如 x可以和 a[1]换,a[1]可以和a[2]换。。。a[k-1]可以和a[k]换,a[k]可以和y换,x就可以和y换啦。
所以就可以建模到一个无向图上,发现一个联通块内的元素之间都是可以随便换的,所以答案就是每个联通分量的颜色序列数的乘积。。
而一个联通分量的颜色序列数是等于 sz!/(col[1]!)(col[2]!)...(col[n]!) ,sz是该联通块的大小。。。
因为很显然这就是可重排列嘛qwq。
但现在最大的问题是我们图的边数还是 O(N^2) 的,直接dfs会gg掉。。。。
现在我们的任务是尽量缩减图的边数但又不影响连通性。
1.连接相同颜色节点的边:
发现都可以向该颜色重量最轻的节点连边,假如 x,y,z 三点颜色相同,w[x]<w[y]<w[z],那么(y,z)之间有边 => (x,y)有边且(x,z)有边 ,但反着不一定成立。
2.连接不同颜色节点的边:
设每种颜色最轻的节点为 lt[i] ,那么我们只需要找到最小的两个 lt[i] ,设为 p,q,每个点只需要向p,q连边即可(如果可以连的话)。
发现颜色具体是啥不影响连边,所以设p的颜色是1,q的颜色是2。
让我们假设 (s,t) 之间有边 (weight(s) + weight(y) <= y), 它们的颜色是 S,T (S<T),那么:
(1) . S==1 且 T==2 , 那么一条可以的路径是 S -> q -> p -> T
(2). S!=1 且 T!=1 ,那么一条可以的路径是 S -> p -> T
(3) . S!=2 且 T!=2 , 那么一条可行的路径是 S -> q -> p -> T (要清楚 T永远是>1的)
可以发现上述三种情况的并集是 (S,T) 可以取的全集,所以证明了这么做是对的。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
#define pb push_back
const int ha=1e9+7,N=200005; inline int add(int x,int y){ x+=y; return x>=ha?x-ha:x;}
inline void ADD(int &x,int y){ x+=y; if(x>=ha) x-=ha;} inline int ksm(int x,int y){
int an=1;
for(;y;y>>=1,x=x*(ll)x%ha) if(y&1) an=an*(ll)x%ha;
return an;
} inline int read(){
int x=0; char ch=getchar();
for(;!isdigit(ch);ch=getchar());
for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
return x;
} vector<int> g[N],now;
int dfn[N],dc,num[N],jc[N],ni[N],ans=1,sz;
int n,X,Y,col[N],w[N],mn[N],p[N],pos[2],C;
bool v[N]; inline void ae(int x,int y){ g[x].pb(y),g[y].pb(x);} inline void init(){
// prepare n! and (n!)^(-1)
jc[0]=1;
for(int i=1;i<=n;i++) jc[i]=jc[i-1]*(ll)i%ha;
ni[n]=ksm(jc[n],ha-2);
for(int i=n;i;i--) ni[i-1]=ni[i]*(ll)i%ha; // prepare edges between different colors
for(int i=1;i<=n;i++)
if(mn[i]<mn[pos[0]]) pos[1]=pos[0],pos[0]=i;
else if(mn[i]<mn[pos[1]]) pos[1]=i;
pos[0]=p[pos[0]],pos[1]=p[pos[1]]; int yz=Y-w[pos[0]],yo=Y-w[pos[1]],cx=col[pos[0]],cy=col[pos[1]]; for(int i=1;i<=n;i++){
C=col[i];
if(C!=cx&&w[i]<=yz) ae(i,pos[0]);
if(C!=cy&&w[i]<=yo) ae(i,pos[1]);
} // prepare edges between the same colors
for(int i=1;i<=n;i++){
C=col[i];
if(i!=p[C]&&w[i]+w[p[C]]<=X) ae(i,p[C]);
}
} void dfs(int x){
v[x]=1,sz++,C=col[x];
if(dfn[C]!=dc) dfn[C]=dc,now.pb(C),num[C]=1;
else num[C]++; for(int i:g[x]) if(!v[i]) dfs(i);
} inline void solve(){
// calculate
for(int i=1;i<=n;i++) if(!v[i]){
dc++,now.clear(),sz=0;
dfs(i),ans=ans*(ll)jc[sz]%ha;
for(int j:now) ans=ans*(ll)ni[num[j]]%ha;
}
} int main(){
memset(mn,0x3f,sizeof(mn)),w[0]=1e9+233; n=read(),X=read(),Y=read();
for(int i=1;i<=n;i++){
C=col[i]=read(),w[i]=read();
if(w[i]<mn[C]) mn[C]=w[i],p[C]=i;
} init(),solve(); printf("%d\n",ans);
return 0;
}
AGC 012 D - Colorful Balls的更多相关文章
- AtCoder Grand Contest 012 D Colorful Balls
题意: 有N个球排成一行,第i个球颜色为ci, 权为wi, 如果两个同色球权值和 <= X 则它们可以交换: 如果两个异色球权值和 <= Y 则它们可以交换:不限制交换次数,求能到达的颜色 ...
- AT2364 Colorful Balls
AT2364 Colorful Balls 题意翻译 N个球排成一排,第i个球有颜色ci和重量wi. Snuke每次可以选择两个颜色相同,且重量之和不超过X的球,交换他们的位置. Snuke每次可以选 ...
- noip2019集训测试赛(二十一)Problem A: Colorful Balls
Problem A: Colorful Balls Description Snuke放了N个一排彩色的球.从左起第i个球的颜色是ci重量是wi她可以通过执行两种操作对这些球重新排序操作1:选择两个相 ...
- CF1478-A. Nezzar and Colorful Balls
CF1478-A. Nezzar and Colorful Balls 题意: 有\(n\)个球,每个球上面都有一个数字\(a_i\),这些数字是组成的序列是非递减的.现在你要给每个球涂色,你必须保证 ...
- AtCoder Grand Contest 012 D:Colorful Balls
题目传送门:https://agc012.contest.atcoder.jp/tasks/agc012_d 题目翻译 给你一排一共\(N\)个球,每个球有一个颜色\(c_i\)和一个重量\(w_i\ ...
- 【AtCoder】【组合数学】【模型转换】Colorful Balls(AGC012)
题意: 有n个球,每个球有两个值,一个是颜色,另一个是重量.可以进行如下的操作任意次: 1.选择两个颜色相同的球,如果这两个球的重量之和小于等于X,就交换这两个球: 2.选择两个颜色不同的球,如果这两 ...
- [AT2364] [agc012_d] Colorful Balls
题目链接 AtCoder:https://agc012.contest.atcoder.jp/tasks/agc012_d 洛谷:https://www.luogu.org/problemnew/sh ...
- AGC 012 C - Tautonym Puzzle
题面在这里! 神仙构造啊qwqwq. 窝一开始只想到一个字符串长度是 O(log(N)^2) 的做法:可以发现一段相同的长度为n的字符串的贡献是 2^(n-1)-1 ,可以把它看成类二进制,枚举用了多 ...
- AGC 012 B - Splatter Painting
题面在这里! (显然首先想到反着做比较简单,每个点取第一次被覆盖到的颜色) 发现d非常小,那么是否可以暴力覆盖呢??? 考虑一个稠密图..暴力肯定就gg了啊... 不过我们可以对每一个点 i 记一个m ...
随机推荐
- Warning: File upload error - unable to create a temporary file in Unknown on line 0
upload_tmp_dir 临时文件夹问题 上传文件提示 Warning: File upload error - unable to create a temporary file in Unkn ...
- 子DIV块中设置margin-top时影响父DIV块位置的解决办法?
解决方法: 1.修改父元素的高度,增加padding-top样式模拟(padding-top:1px:常用) 2.为父元素添加overflow:hidden:样式即可(完美) 3.为父元素或者子元素声 ...
- Centos 7 安装jdk1.7
在linux中安装jdk是很平凡的事情了,刚学习linux给自己留下一笔记.刚安装centos其中可以会附带jdk,但是这并不影响,只要下载自己的jdk然后替换相对应的环境变量即可. 1.下载相对应的 ...
- 上传漏洞新姿势(限Linux)
服务器:Linux当前环境:nginx/1.4.7PHP版本:PHP Version 7.0.0 上传情况简介:上传 111.jpg111 确实可以成功的但是上传 1.php.jpg1111.1 ...
- 调试应用程序(Debugging Applications)
调试应用程序(Debugging Applications)¶ Phalcon中提供了提供了几种调试级别即通知,错误和异常. 异常类 Exception class 提供了错误发生时的一些常用的调试信 ...
- 安全测试===Web 安全渗透方面的学习路线
作者:向生李链接:https://www.zhihu.com/question/21914899/answer/39344435来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...
- windows7 能连接移动硬盘 无法显示盘符
右键点我的电脑,管理里,点磁盘管理,看盘认到没,有时候认到了但是没给盘符,需要自己手动给一个
- Sqlserver获取所有数据库名,表信息,字段信息,主键信息,以及表结构等。
--获取所有数据库名: SELECT name FROM master..sysdatabases WHERE name NOT IN ( 'master', 'model', 'msdb', 'te ...
- [hadoop][基本原理]zookeeper简单使用
代码:https://github.com/xufeng79x/ZkClientTest 1.简介 zookeeper的基本原理和使用场景描述可参考:[hadoop][基本原理]zookeeper基本 ...
- mongodb实现批量修改数据
var rds = db.REGIPATIENTREC.find({mzh:{$lt:"0"},usrOrg:"石景山中西医结合医院"}); var show ...