Description

有n对夫妇,一开始夫妇之间互不认识,若两男或两女成为朋友,称他们为"熟人","熟人"关系具有传递性,即若a熟b且b熟c则a熟c.若两组夫妇的丈夫互相为熟人且妻子也相互为熟人则称他们为"熟悉的一对",现在给出q个事件,每个事件会使得两男或两女成为朋友,并在每次事件之后计算"熟悉的一对"的个数.

Input

第一行一个数T表示数据组数
接下来n,q表示对数和事件数
接下来q行,每行t,a,b,若t=1,表示男a和男b成为朋友,t=2,表示女a和女b成为朋友

Output

设当前是第i个操作,y_i为本次事件之后的答案,令z_i=i*y_i,请输出z_1+z_2+...+z_q模10^9+7
题意简化为维护两个图,支持在一个图中连边和询问有多少点对在两个图中都连通
用两个并查集分别维护两个图中的连通性,用一个hashmap维护一个n*n的二维数组,f[x][y]表示在并查集1中属于集合x,在并查集2中属于集合y的点的个数
每次在一个图中连边时,若两侧连通则忽略,不联通则遍历小的一个联通块,通过计算在另一个图中跨过两个联通块的联通块更新答案
均摊时间复杂度O(Tnlogn)
  1. #include<cstdio>#include<vector>
  2. const int P=1e9+,N=1e6+;
  3. inline int read(){
  4. int x=,c=getchar();
  5. while(c>''||c<'')c=getchar();
  6. while(c>=''&&c<='')x=x*+c-'',c=getchar();
  7. return x;
  8. }
  9. inline void exch(int&a,int&b){int c=a;a=b;b=c;}namespace Map{
  10. const int mx=;
  11. unsigned int nw=;
  12. unsigned int xs[mx],ys[mx],zs[mx],ds[mx];
  13. inline void clear(){
  14. nw++;
  15. }
  16. inline int get(unsigned int x,unsigned int y,int inc){
  17. unsigned int w=(x*+y*+)%mx;
  18. while(ds[w]==nw){
  19. if(xs[w]==x&&ys[w]==y){
  20. int v=zs[w];
  21. zs[w]+=inc;
  22. return v;
  23. }
  24. w+=;
  25. if(w>=mx)w-=mx;
  26. }
  27. ds[w]=nw;
  28. xs[w]=x;ys[w]=y;zs[w]=inc;
  29. return ;
  30. }
  31. }
  32. int T,n,m,now=,Ans,ans;
  33. int h1[N],h2[N],f1[N],f2[N],sz1[N],sz2[N],nx1[N],nx2[N];
  34. int t[N],d[N];
  35. std::vector<int>v1[N],v2[N];
  36. int main(){
  37. T=read();
  38. while(T--){
  39. n=read();m=read();
  40. Ans=ans=;
  41. Map::clear();
  42. for(int i=;i<=n;i++){
  43. Map::get(i,i,);
  44. f1[i]=f2[i]=i;
  45. v1[i].clear();v2[i].clear();
  46. v1[i].push_back(i);
  47. v2[i].push_back(i);
  48. }
  49. for(int i=,op,a,b;i<=m;++i){
  50. op=read();a=read();b=read();
  51. ++now;
  52. if(op==){
  53. if(f1[a]!=f1[b]){
  54. if(v1[f1[a]].size()>v1[f1[b]].size())exch(a,b);
  55. std::vector<int>&vc=v1[f1[a]];
  56. for(int x=;x<vc.size();x++){
  57. int p=vc[x];
  58. int f=f2[p];
  59. if(d[f]!=now)d[f]=now,ans=(ans+Map::get(f1[p],f,-)*1ll*Map::get(f1[b],f,)%P)%P;
  60. else Map::get(f1[p],f,-),Map::get(f1[b],f,);
  61. f1[p]=f1[b];
  62. v1[f1[b]].push_back(p);
  63. }
  64. vc.clear();
  65. }
  66. }else{
  67. if(f2[a]!=f2[b]){
  68. if(v2[f2[a]].size()>v2[f2[b]].size())exch(a,b);
  69. std::vector<int>&vc=v2[f2[a]];
  70. for(int x=;x<vc.size();x++){
  71. int p=vc[x];
  72. int f=f1[p];
  73. if(d[f]!=now)d[f]=now,ans=(ans+Map::get(f,f2[p],-)*1ll*Map::get(f,f2[b],)%P)%P;
  74. else Map::get(f,f2[p],-),Map::get(f,f2[b],);
  75. f2[p]=f2[b];
  76. v2[f2[b]].push_back(p);
  77. }
  78. vc.clear();
  79. }
  80. }
  81. Ans=(Ans+ans*1ll*i%P)%P;
  82. }
  83. printf("%d\n",Ans);
  84. }
  85. return ;
  86. }

bzoj4153 [Ipsc2015]Familiar Couples的更多相关文章

  1. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  2. Sicily 1021. Couples

    题目地址:1021. Couples 思路: 想清楚了这道题其实很简单.利用夫妻出现的位置作为下标,并设为同一值,第一对夫妻值为1,第二对为2,以此类推,存储完毕即可进入下一步. 利用栈这个数据结构: ...

  3. Julia is a high-level, high-performance dynamic programming language for technical computing, with syntax that is familiar to users of other technical

    http://julialang.org/ julia | source | downloads | docs | blog | community | teaching | publications ...

  4. [LeetCode] Couples Holding Hands 两两握手

    N couples sit in 2N seats arranged in a row and want to hold hands. We want to know the minimum numb ...

  5. [Swift]LeetCode765. 情侣牵手 | Couples Holding Hands

    N couples sit in 2N seats arranged in a row and want to hold hands. We want to know the minimum numb ...

  6. [CC-COUPLES]Couples sit next to each other

    [CC-COUPLES]Couples sit next to each other 题目大意: 有\(n(n\le5\times10^5)\)对小伙伴共\(2n\)个人坐成一圈.刚开始编号为\(i\ ...

  7. 每日英语:Why Rate Your Marriage? A Numerical Score Can Help Couples Talk About Problems

    When marriage therapist Sharon Gilchrest O'Neill met with new clients recently, she asked them why t ...

  8. ZOJ 3161 Damn Couples 动态规划 难度:2

    Damn Couples Time Limit: 1 Second      Memory Limit: 32768 KB As mentioned in the problem "Coup ...

  9. LeetCode765. Couples Holding Hands

    N couples sit in 2N seats arranged in a row and want to hold hands. We want to know the minimum numb ...

随机推荐

  1. Oracle 与Sql Server常用函数对比

    来自:http://topic.csdn.net/u/20080704/08/b2b8c42f-b0d6-4cda-98b1-6e4a279b4ff8.html 感谢楼主 函数 SQLServer和O ...

  2. 难度2:ASCII码排序

    ASCII码排序 难度:2描述: 输入三个字符(可以重复)后,按各字符的ASCII码从小到大的顺序输出这三个字符. 输入: 第一行输入一个数N,表示有N组测试数据.后面的N行输入多组数据,每组输入数据 ...

  3. ora-01830:日期格式图片在转换整个输入字符串之前结束

    在to_date的时候因为 fldsj这个字段的大小 与 ‘yyyy-MM-dd’不符合 所以需要截取下fldsj字段的大小  to_char(to_date(substr(fldsj,1,10),' ...

  4. 20165210 Java第八周学习总结

    20165210 Java第八周学习总结 教材内容学习 - 第十二章学习总结 进程与线程 操作系统与进程 Java中的线程 Java的多线程机制 主线程 线程的状态与生命周期 1. 新建 2. 运行 ...

  5. apsx 页面 if(!ispostback)其用法和作用 什么时候该用?

    一个页面第一次显示的时候 isPostBack=false 然后你在这个页面上点击按钮或其它东西提交的时候, isPostBack=true 一般这个函数里面的内容是指第一次打开这个页面的时候要做的事 ...

  6. Intellij Idea2016.3 svn服务器拉取代码

    1.修改idea的默认配置,取消SVN设置里的两个勾 2.拉取代码 3.输入SVN仓库的地址,然后checkout 即可

  7. HDU 1853

    http://acm.hdu.edu.cn/showproblem.php?pid=1853 和下题一模一样,求一个图环的并,此题的题干说的非常之裸露 http://www.cnblogs.com/x ...

  8. 【c++基础】判断是否到文件末尾-eof函数

    前言 读取文件内容时,需要判断是否到文件末尾,此时用到eof函数. 函数定义 Check whether eofbit is set Returns true if theeofbiterror st ...

  9. 简单介绍Spring的ContextLoaderListener

    在开发Spring的Web项目中,通常我们都会在web.xml中配置一个Spring的核心监听器,就是把Spring的IOC容器纳入Servlet容器中,配置如下: <listener> ...

  10. 粘包、拆包发生原因滑动窗口、MSS/MTU限制、Nagle算法

    [TCP协议](3)---TCP粘包黏包 [TCP协议](3)---TCP粘包黏包 有关TCP协议之前写过两篇博客: 1.[TCP协议](1)---TCP协议详解 2.[TCP协议](2)---TCP ...