LINK:

在说这道题之前吐槽一下今天的日子 520 = 1+1+4+514. /cy



这道题今天做的非常失败 一点分都没拿到手 关键是今天的T3 把我整个人给搞崩了。

先考虑 如果得到了这么一张图 怎么得到染色的方案数。

发现很难计算 容斥?总方案-2个相同的+3个相同的 我都觉得不太靠谱且复杂度过高。

考虑直接用乘法原理计数 随便从一个点dfs 然后把相邻的点能选择的方案-1.

这样也是错误的 如一个四个点的环(可能不满足题目中的条件类似的 不过也是可以构造出来的。

第一个点贡献为n 第二个点贡献为n-1 第三个点贡献为n-1 第四个点贡献为n-2

容易发现端倪 如果第三个点和第一个点颜色一样 那么第四个点方案就可以为 n-1了。

所以这是不正确的。

进一步的我们发现 关键是和某个点相邻的多个点可能没有边相连 所以 他们颜色可能相同。

结合题目条件 一个编号比周围都小的点一定没有这个限制。

那么从大到小考虑 染色就可以使相邻的点 颜色不同了。

考虑50分的做法 把图建出来 暴力染色 即可。

这里建图 我直接枚举了两个点b c 寻找是否存在一个a 满足 a<b,a<c 且a和b 以及a和c有边相连。

bitset优化一下即可。

const int MAXN=1002;
int n,m;
bitset<MAXN>b[MAXN],s,cc;
int a[MAXN],vis[MAXN],ans=1;
inline int mul(int a,int b){return (ll)a*b%mod;}
inline int add(int a,int b){return a+b>=mod?a+b-mod:a+b;}
inline int mus(int a,int b){return a-b<0?a-b+mod:a-b;}
inline int ksm(int b,int p)
{
int cnt=1;
while(p)
{
if(p&1)cnt=mul(cnt,b);
b=mul(b,b);p=p>>1;
}
return cnt;
}
inline void dfs(int x)
{
vis[x]=1;ans=mul(ans,a[x]);
for(int i=1;i<=n;++i)
{
if(!b[x][i])continue;
if(!vis[i])--a[i];
}
for(int i=1;i<=n;++i)
{
if(!b[x][i])continue;
if(!vis[i])dfs(i);
}
}
int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
get(n);get(m);
rep(1,m,i)
{
int get(x),get(y);
b[x][y]=b[y][x]=1;
}
s.reset();
rep(2,n,i)
{
s[i-1]=1;
rep(i+1,n,j)
{
if(b[i][j])continue;
cc=b[i]&b[j]&s;
if(cc.count())b[i][j]=b[j][i]=1;
}
}
rep(1,n,i)a[i]=n;
//rep(1,n,i){rep(1,n,j)cout<<b[i][j]<<' ';cout<<endl;}
fep(n,1,i)
{
int cnt=0;
rep(i+1,n,j)if(b[i][j])++cnt;
ans=mul(ans,n-cnt);
}
put(ans);return 0;
}

考虑正解:

此时问题变成了 求每个点和其相连的 编号比其大的个数.

还是考虑题目中的a,b,c 和刚才的暴力一样需要从小到大做。

考虑最小的a 显然可以直接得到答案。

此时容易想到 和a相连的那些点必然也相连。

在从小到大考虑到某个和a相连的点w的时候 w和a能连得集合是相同的。

把a的集合拿过来用即可得到和自己相连的点集。

可以发现这个关系具有传递性 且每次只会传递到一个点上。

所以 由于要支持查询最小值和数量 所以可以利用set 进行启发式合并。nlog^2

当然也可以使用线段树合并来优化复杂度.nlog

值得注意的是 需要去重 所以无法使用可并堆/堆 来做。这里给出线段树合并的code。

const int MAXN=1000010;
int n,m,id;
int a[MAXN],root[MAXN],ans=1;
inline int mul(int a,int b){return (ll)a*b%mod;}
inline int add(int a,int b){return a+b>=mod?a+b-mod:a+b;}
inline int mus(int a,int b){return a-b<0?a-b+mod:a-b;}
inline int ksm(int b,int p)
{
int cnt=1;
while(p)
{
if(p&1)cnt=mul(cnt,b);
b=mul(b,b);p=p>>1;
}
return cnt;
}
struct wy{int l,r;int sum;}t[MAXN*30];
inline void insert(int &p,int l,int r,int x)
{
if(!p)p=++id;++sum(p);
if(l==r)return;
int mid=(l+r)>>1;
if(x<=mid)insert(l(p),l,mid,x);
else insert(r(p),mid+1,r,x);
}
inline int ask(int p,int l,int r)
{
if(!sum(p))return 0;
--sum(p);
if(l==r)return l;
int mid=(l+r)>>1;
if(sum(l(p)))return ask(l(p),l,mid);
return ask(r(p),mid+1,r);
}
inline int merge(int x,int y,int l,int r)
{
if(!x||!y)return x|y;
if(l==r)return x;
int mid=(l+r)>>1;
l(x)=merge(l(x),l(y),l,mid);
r(x)=merge(r(x),r(y),mid+1,r);
sum(x)=sum(l(x))+sum(r(x));
return x;
}
int main()
{
freopen("1.in","r",stdin);
//freopen("a.out","w",stdout);
get(n);get(m);
rep(1,m,i)
{
int x,y;
get(x);get(y);
if(x>y)swap(x,y);
insert(root[x],1,n,y);
}
rep(1,n,i)
{
ans=mul(ans,n-sum(root[i]));
//cout<<sum(root[i])<<endl;
int ww=ask(root[i],1,n);
//cout<<sum(root[i])<<endl;
if(ww)root[ww]=merge(root[ww],root[i],1,n);
}
put(ans);
return 0;
}

5.20 省选模拟赛 T1 图 启发式合并 线段树合并 染色计数问题的更多相关文章

  1. 2016湖南省赛 I Tree Intersection(线段树合并,树链剖分)

    2016湖南省赛 I Tree Intersection(线段树合并,树链剖分) 传送门:https://ac.nowcoder.com/acm/contest/1112/I 题意: 给你一个n个结点 ...

  2. 【洛谷比赛】[LnOI2019]长脖子鹿省选模拟赛 T1 题解

    今天是[LnOI2019]长脖子鹿省选模拟赛的时间,小编表示考的不怎么样,改了半天也只会改第一题,那也先呈上题解吧. T1:P5248 [LnOI2019SP]快速多项式变换(FPT) 一看这题就很手 ...

  3. 【2018.06.26NOIP模拟】T1纪念碑square 【线段树】*

    [2018.06.26NOIP模拟]T1纪念碑square 题目描述 2034年,纪念中学决定修建校庆100周年纪念碑,作为杰出校友的你被找了过来,帮校方确定纪念碑的选址. 纪念中学的土地可以看作是一 ...

  4. 7.9模拟赛T1图的遍历(dfs)

    图的遍历(dfs) [题目描述] 对于一个有向图G来说,我们存在一个经典的遍历算法,就是DFS (深度优先搜索遍历).将G以1号点为起点进行DFS后,我们可以 得到G的一棵DFS遍历树T.就此,我们可 ...

  5. 5.15 省选模拟赛 T1 点分治 FFT

    LINK:5.15 T1 对于60分的暴力 都很水 就不一一赘述了. 由于是询问所有点的这种信息 确实不太会. 想了一下 如果只是询问子树内的话 dsu on tree还是可以做的. 可以自己思考一下 ...

  6. NOI 2019 省选模拟赛 T1【JZOJ6082】 染色问题(color) (多项式,数论优化)

    题面 一根长为 n 的无色纸条,每个位置依次编号为 1,2,3,-,n ,m 次操作,第 i 次操作把纸条的一段区间 [l,r] (l <= r , l,r ∈ {1,2,3,-,n})涂成颜色 ...

  7. 洛谷[LnOI2019]长脖子鹿省选模拟赛t1 -> 快速多项式变换

    快速多项式 做法:刚拿到此题有点蒙,一开始真没想出来怎么做,于是试着去自己写几个例子. 自己枚举几种情况之后就基本看出来了,其实本题中 n 就是f(m)在m进制下的位数,每项的系数就是f(m)在m进制 ...

  8. 5.20 省选模拟赛 求和 组合数的性质 EGF CRT

    LINK:求和 绝妙的一道题目.没做绝对亏了. 对于第一个subtask 考虑直接递推出组合数. 对于第二个subtask 考虑EGF 设两个EGF 都只含偶数项指标且系数为1的那种 一个到n一个到m ...

  9. 5.19 省选模拟赛 T1 小B的棋盘 双指针 性质

    LINK:小B的棋盘 考试的时候没有认真的思考 导致没做出来. 容易发现 当k>=n的时候存在无限解 其余都存在有限解 对于30分 容易想到暴力枚举 对称中心 然后 n^2判断. 对于前者 容易 ...

随机推荐

  1. Meta标签大全_web开发常用meta整理

    meta标签提供关于HTML文档的元数据.元数据不会显示在页面上,但是对于机器是可读的.它可用于浏览器(如何显示内容或重新加载页面),搜索引擎(关键词),或其他 web 服务. 必要属性 属性 值 描 ...

  2. Spark TempView和GlobalTempView的区别

    Spark TempView和GlobalTempView的区别 TempView和GlobalTempView在spark的Dataframe中经常使用,两者的区别和应用场景有什么不同. 我们以下面 ...

  3. 「JLOI2015」城池攻占 可并堆

    传送门 分析 如果直接暴力枚举的话肯定会超时 我们可以从下往上遍历,维护一个小根堆 每次到达一个节点把战败的骑士扔出去 剩下的再继续向上合并,注意要维护一下其实的战斗力 可以像线段树那样用一个lazy ...

  4. 洛谷CF1292A NEKO's Maze Game,还是思维。。。

    题目直接找链接 题意: 有一个2*n大的平面,有的格子不能走,有的格子可以走,最初状态所有格子都可以走,有q个操作,每个操作都把某个格子变化一下:能走变不能走,不能走变能走,输出每次操作之后能否从1, ...

  5. 协同合约HACKATHON 0X03;

    协同合约HACKATHON 0X03; 使用Fetch.AI技术开发一个共享行程协同合约.超过100,000个FET代币奖励. 介 绍 拼车是对你的钱包和环境都非常有益的,因此UberPool™等共享 ...

  6. redis cluster info显示cluster_state:fail解决方案

    1.查看错误信息: 1.1 错误信息(1) 127.0.0.1:7000> get name (error) CLUSTERDOWN The cluster is down 127.0.0.1: ...

  7. 数据可视化之powerBI技巧(二十)采悟:创建度量值,轻松进行分组统计

    上一篇文章中的分组,都是通过新建列的方式实现的,直观上比较容易理解.不过这样都修改了原始数据的结构,如果我们不在源表上进行修改,直接通过度量值的方式来进行分组,是否可以实现呢? 答案当然是肯定的. 采 ...

  8. 迎难而上ArrayList,源码分析走一波

    先看再点赞,给自己一点思考的时间,思考过后请毫不犹豫微信搜索[沉默王二],关注这个长发飘飘却靠才华苟且的程序员.本文 GitHub github.com/itwanger 已收录,里面还有技术大佬整理 ...

  9. 10-Python文件操作

    一.文本文件和二进制文件 文本文件存储的是普通“字符”文本,python 默认为unicode 字符集(两个字节表示 一个字符,最多可以表示:65536 个). 二进制文件:二进制文件吧数据内容用‘字 ...

  10. 阿里面试官:这些软件测试面试题都答对了,I want you!

    [ 你悄悄来,请记得带走一丝云彩 ] 测试岗必知必会 01请描述如何划分缺陷与错误严重性和优先级别? 给软件缺陷与错误划分严重性和优先级的通用原则: 1. 表示软件缺陷所造成的危害和恶劣程度. 2. ...