【cf859E】Desk Disorder

Portal --> cf859E

Solution

??  我们可以将每一个人看成一条边,将位置看成点,然后一个人在新的方案中可以选择的位置就是这条边连接的两个点,然后我们就得到了一个图

?  注意到这个图可能包含多个连通块,每个连通块可以独立计算,那么最后的答案应该就是各个连通块计算结果的乘积,那么现在我们的问题就是怎么算一个连通块内的答案

??  考虑一个包含\(n\)个点的连通块,我们来分析一下这个连通块的性质:首先因为这是一个连通块,所以边数\(m>=n-1\),然后注意到这题中有一个性质:原方案中没有两个人选的是同一个位置(点),所以我们可以得到边数\(m<=n\)

?  所以一个包含\(n\)个点的连通块只可能有两种情况:

1、\(m=n-1\):这个时候是一棵树,那么答案就应该是\(n\)(树中的节点个数),具体的话就是考虑哪个节点没有人选,所以就有\(n\)种方案

2、\(m=n\):这个时候如果是一个基环树,考虑环中的边数和点数相同,所以环中所有的点只能被环上的边选,这样一来树中能选的点数和要选的边数相等,所以树中的方案是唯一的,环中的方案只有两种,所以这个时候有\(2\)中方案;但是!如果说这个环是个自环,那就只有一种方案了,因为环中不能移动

?  所以我们直接并查集判断一下统计一下就好了

?  

??  代码大概长这个样子

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=1e5+10,MOD=1e9+7;
int f[N*2],in[N*2],cnt[N*2],mark[N*2];
int n,m,tot,ans;
int get_f(int x){return f[x]=f[x]==x?f[x]:get_f(f[x]);}
int mul(int x,int y){return 1LL*x*y%MOD;}

int main(){
#ifndef ONLINE_JUDGE
    freopen("a.in","r",stdin);
#endif
    int x,y;
    scanf("%d",&n);
    for (int i=1;i<=2*n;++i) f[i]=i,cnt[i]=1,mark[i]=0;
    ans=1;
    int tmp=0;
    for (int i=1;i<=n;++i){
        scanf("%d%d",&x,&y);
        get_f(x); get_f(y);
        mark[x]=1;
        tmp=max(tmp,max(x,y));
        if (x==y) continue;
        if (f[x]==f[y]) ans=mul(ans,2);
        cnt[f[y]]+=cnt[f[x]];
        f[f[x]]=f[y];
    }
    int debug=0;
    for (int i=1;i<=2*n;++i)
        if (!mark[i])
            ans=mul(ans,cnt[i]),++debug;
    printf("%d\n",ans);
}

原文地址:https://www.cnblogs.com/yoyoball/p/9543299.html

时间: 2024-11-11 10:39:24

【cf859E】Desk Disorder的相关文章

「CF859E」Desk Disorder

传送门 Luogu 解题思路 一眼想到二分图:但是求不了最大匹配方案数 oho. 于是考虑这么建图: 直接将一个人可以去的两把椅子连边,然后原图中的2n个点就会形成许多联通块,这个可以分步计数. 又因为每个联通块只会是一棵树或是环套树,所以分类讨论一个联通块内如何计数: 若该联通块是一棵树(边数=点数-1),显然方案数就是点数(每次考虑那个点不被匹配即可) 若该联通块是一棵环套树(边数=点数),环上的点只能用环上的点匹配,那么每一棵树的方案固定,环上有两种方案,所以方案数就是2,但是如果环是一个

投行知识普及【转】

整个金融行业大致分为buy side和sell side两大类.Sell side做的主要是把各种asset变成各种金融产品,提供给市场.Sell side主要指的是通常意义上的投行.投行内部结构也很复杂,按照产品分大致分为fixed income和equity两大类.按照业务分大致分为IBD, sales & trading,equity research, asset management(这部分和buy side性质是类似的)等.IBD是最传统的投资银行业务,靠近的是corporate一边

【转】SYSTEM_HANDLE_INFORMATION

typedef struct _SYSTEM_HANDLE_INFORMATION{ ULONG ProcessId; UCHAR ObjectTypeNumber; UCHAR Flags; USHORT Handle; PVOID Object; ACCESS_MASK GrantedAccess; /* ProcessId: 进程标识符 ObjectTypeNumber; 打开的对象的类型 Flags: 句柄属性标志 Handle: 句柄数值,在进程打开的句柄中唯一标识某个句柄 Objec

HDU1103 Flo&#39;s Restaurant 【模拟】

Flo's Restaurant Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1112    Accepted Submission(s): 342 Problem Description Sick and tired of pushing paper in the dreary bleary-eyed world of finan

【模拟】Flo&#39;s Restaurant

[poj2424]Flo's Restaurant Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2960   Accepted: 929 Description Sick and tired of pushing paper in the dreary bleary-eyed world of finance, Flo ditched her desk job and built her own restaurant.

【转】常用快捷键操作

常用快捷键大全 目录 一.系统快捷键 二.常用系统命令 三.QQ快捷键 四.IE浏览器快捷键使用大全 五.Word 中的快捷键 六.Excel 中的快捷键 七.PowerPoint 中的快捷键 八.Visual Studio 九.Eclipse 十.Photoshop 十一.批处理指令 十二.安装操作系统 一.系统快捷键 F1 帮助F2 改名F3 搜索 F4 地址F5 刷新F6 切换F8 安全模式F10 菜单F11 全屏INS 插入模式PRTSCSYSRQ 截屏CAPSLOCK 大写字母锁定DE

【POJ3481】【splay】Double Queue

Description The new founded Balkan Investment Group Bank (BIG-Bank) opened a new office in Bucharest, equipped with a modern computing environment provided by IBM Romania, and using modern information technologies. As usual, each client of the bank i

【Kettle】4、SQL SERVER到SQL SERVER数据转换抽取实例

1.系统版本信息 System:Windows旗舰版 Service Pack1 Kettle版本:6.1.0.1-196 JDK版本:1.8.0_72 2.连接数据库 本次实例连接数据库时使用全局变量. 2.1 创建新转换:spoon启动后,点击Ctrl+N创建新转换 2.2 在新转换界面中,右键点击DB连接,系统会弹出[数据库连接]界面. windows系统环境下,可用${}获取变量的内容. 说明: 连接名称:配置数据源使用名称.(必填) 主机名称:数据库主机IP地址,此处演示使用本地IP(

详解go语言的array和slice 【二】

上一篇  详解go语言的array和slice [一]已经讲解过,array和slice的一些基本用法,使用array和slice时需要注意的地方,特别是slice需要注意的地方比较多.上一篇的最后讲解到创建新的slice时使用第三个索引来限制slice的容量,在操作新slice时,如果新slice的容量大于长度时,添加新元素依然后使源的相应元素改变.这一篇里我会讲解到如何避免这些问题,以及迭代.和做为方法参数方面的知识点. slice的长度和容量设置为同一个值 如果在创建新的slice时我们把