【BZOJ4298】[ONTAK2015]Bajtocja

Description

给定d张无向图,每张图都有n个点。一开始,在任何一张图中都没有任何边。接下来有m次操作,每次操作会给出a,b,k,意为在第k张图中的点a和点b之间添加一条无向边。你需要在每次操作之后输出有序数对(a,b)的个数,使得1<=a,b<=n,且a点和b点在d张图中都连通。

Input

第一行包含三个正整数d,n,m(1<=d<=200,1<=n<=5000,1<=m<=1000000),依次表示图的个数,点的个数和操作的个数。

接下来m行,每行包含三个正整数a,b,k(1<=a,b<=n,1<=k<=d),依次描述每一个操作。

Output

输出m行m个正整数,依次表示每次操作之后满足条件的有序数对(a,b)的个数。

Sample Input

3 4 10

1 2 1

2 1 2

1 2 3

3 4 1

1 3 2

2 3 3

2 4 2

3 4 3

3 4 2

1 3 1

Sample Output

4

4

6

6

6

6

6

8

8

16

神仙题啊。

考虑给每个图开一个并查集。设\(f_{i,k}\)表示第\(i\)个点在第\(k\)张图中并查集的根。然后我们对于每个点\(i\),我们将\(d\)张图中的\(f_i\)当成一个字符串并算出\(hash\)值。如果两个点\(i,j\)的\(hash\)值相同,则他们在每一张图中都连通。

具体操作可以开一个\(hash\)表。然后并查集启发式合并。还要用\(unsigned\ long\ long\)。

代码:

  1. #include<bits/stdc++.h>
  2. #define ll long long
  3. #define N 5005
  4. #define M 1000005
  5. #define D 205
  6. #define ull unsigned long long
  7. using namespace std;
  8. inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}
  9. int d,n,m;
  10. struct road {int to,next;};
  11. ll ans;
  12. const int mod=10000007;
  13. const ull p=2337;
  14. ull pw[D];
  15. ull g[N];
  16. struct Hash {
  17. int h[mod],cnt;
  18. int size[N*N/5],nxt[N*N/5];
  19. ull val[N*N/5];
  20. void Insert(ull x) {
  21. int v=x%mod;
  22. for(int i=h[v];i;i=nxt[i]) {
  23. if(val[i]==x) {
  24. size[i]++;
  25. ans+=2*size[i]-1;
  26. return ;
  27. }
  28. }
  29. val[++cnt]=x;
  30. nxt[cnt]=h[v];
  31. size[cnt]=1;
  32. h[v]=cnt;
  33. ans++;
  34. }
  35. void Del(ull x) {
  36. int v=x%mod;
  37. for(int i=h[v];i;i=nxt[i]) {
  38. if(val[i]==x) {
  39. ans-=2*size[i]-1;
  40. size[i]--;
  41. return ;
  42. }
  43. }
  44. }
  45. }ha;
  46. struct BCJ {
  47. int id;
  48. int f[N],size[N];
  49. void Init() {for(int i=1;i<=n;i++) f[i]=i,size[i]=1;}
  50. int Getf(int v) {return v==f[v]?v:f[v]=Getf(f[v]);}
  51. road s[N<<1];
  52. int h[N],cnt;
  53. void add(int i,int j) {s[++cnt]=(road) {j,h[i]};h[i]=cnt;}
  54. void dfs(int v,int fa) {
  55. ha.Del(g[v]);
  56. g[v]-=f[v]*pw[id-1];
  57. f[v]=fa;
  58. g[v]+=f[v]*pw[id-1];
  59. ha.Insert(g[v]);
  60. for(int i=h[v];i;i=s[i].next) {
  61. int to=s[i].to;
  62. dfs(to,fa);
  63. }
  64. }
  65. void Merge(int a,int b) {
  66. a=Getf(a),b=Getf(b);
  67. if(a==b) return ;
  68. if(size[a]>size[b]) swap(a,b);
  69. add(b,a);
  70. size[b]+=size[a];
  71. dfs(a,b);
  72. }
  73. }T[D];
  74. int main() {
  75. d=Get(),n=Get(),m=Get();
  76. for(int i=1;i<=d;i++) T[i].Init();
  77. pw[0]=1;
  78. for(int i=1;i<=d;i++) pw[i]=pw[i-1]*p;
  79. for(int i=1;i<=d;i++) T[i].id=i;
  80. for(int i=1;i<=n;i++) {
  81. for(int j=1;j<=d;j++) g[i]=g[i]*p+i;
  82. ha.Insert(g[i]);
  83. }
  84. int x,y,z;
  85. for(int i=1;i<=m;i++) {
  86. x=Get(),y=Get(),z=Get();
  87. T[z].Merge(x,y);
  88. cout<<ans<<"\n";
  89. }
  90. return 0;
  91. }

【BZOJ4298】[ONTAK2015]Bajtocja的更多相关文章

  1. 【BZOJ4278】[ONTAK2015]Tasowanie 后缀数组

    [BZOJ4278][ONTAK2015]Tasowanie Description 给定两个数字串A和B,通过将A和B进行二路归并得到一个新的数字串T,请找到字典序最小的T. Input 第一行包含 ...

  2. 【BZOJ4275】[ONTAK2015]Badania naukowe DP

    [BZOJ4275][ONTAK2015]Badania naukowe Description 给定三个数字串A,B,C,请找到一个A,B的最长公共子序列,满足C是该子序列的子串. Input 第一 ...

  3. 【BZOJ4245】[ONTAK2015]OR-XOR 贪心

    [BZOJ4245][ONTAK2015]OR-XOR Description 给定一个长度为n的序列a[1],a[2],...,a[n],请将它划分为m段连续的区间,设第i段的费用c[i]为该段内所 ...

  4. 【BZOJ4281】[ONTAK2015]Związek Harcerstwa Bajtockiego LCA

    [BZOJ4281][ONTAK2015]Związek Harcerstwa Bajtockiego Description 给定一棵有n个点的无根树,相邻的点之间的距离为1,一开始你位于m点.之后 ...

  5. 【BZOJ4276】[ONTAK2015]Bajtman i Okrągły Robin 线段树优化建图+费用流

    [BZOJ4276][ONTAK2015]Bajtman i Okrągły Robin Description 有n个强盗,其中第i个强盗会在[a[i],a[i]+1],[a[i]+1,a[i]+2 ...

  6. #5【BZOJ4275】[ONTAK2015]Badania

    Description 给定三个数字串A,B,C,请找到一个A,B的最长公共子序列,满足C是该子序列的子串. Input 第一行包含一个正整数n(1<=n<=3000),表示A串的长度. ...

  7. 【bzoj4278】[ONTAK2015]Tasowanie 贪心+后缀数组

    题目描述 给定两个数字串A和B,通过将A和B进行二路归并得到一个新的数字串T,请找到字典序最小的T. 输入 第一行包含一个正整数n(1<=n<=200000),表示A串的长度. 第二行包含 ...

  8. 【bzoj4281】[ONTAK2015]Związek Harcerstwa Bajtockiego 树上倍增+LCA

    题目描述 给定一棵有n个点的无根树,相邻的点之间的距离为1,一开始你位于m点.之后你将依次收到k个指令,每个指令包含两个整数d和t,你需要沿着最短路在t步之内(包含t步)走到d点,如果不能走到,则停在 ...

  9. 【bzoj4245】[ONTAK2015]OR-XOR

    利用前缀和选m个区间等价于选m个数 从最高位开始找,如果这一位至少有m个0,则可以为0,该位为1的后面就不可以选了. 还要注意,最后一个数如果该位为1,那么这一位必须为1,然后要从62开始枚举,而不是 ...

随机推荐

  1. linux基本命令手册

    常用指令 ls         显示文件或目录 -l           列出文件详细信息l(list) -a          列出当前目录下所有文件及目录,包括隐藏的a(all) mkdir    ...

  2. 4. explain简介

    一.是什么 使用 explain 关键字可以模拟优化器执行SQl查询语句,从而知道 mysql 是如何处理你的sql语句的.分析你的查询语句或是表的结构的性能瓶颈. 二.能干嘛 表的读取顺序 数据读取 ...

  3. ubuntu中subline无法使用搜狗输入法

    今天使用subline编写python程序,发现在ubuntu下无法调用搜狗输入法输入中文,结果一番搜索发现github上的sublime-text-imfix项目能修复此问题,项目地址是:https ...

  4. http协议、web服务器、并发服务器(下)

    Web静态服务器-5-非堵塞模式 单进程非堵塞模型 import socket import time def main(): tcp_socket_server = socket.socket(so ...

  5. Mac下写博客工具ecto相关资料

    下载地址: https://www.macupdate.com/app/mac/8918/ecto 相关注册码: http://www.cnblogs.com/yssgyw/p/3284501.htm ...

  6. Mac包管理神器Homebrew

    概念 简称brew,是Mac OSX上的软件包管理工具,能在Mac中方便的安装软件或者卸载软件,相当于Red hat的yum.Ubuntu的apt-get. 安装命令 ruby -e "$( ...

  7. MySQL主从 常见的错误及解决方案

    一.错误日志解析: (1) [ERROR]1452:无法在外键的表插入参考主键没有的数据 1452:无法在外键的表插入或更新参考主键没有的数据.由于item_discovery.itemid字段(外键 ...

  8. navicate 远程无法链接linux上mysql数据库问题

    1. 先确认阿里云是否放开了3306权限 (开启阿里云服务器端口) 2. 连接linux,登录数据库:mysql -uroot -p 修改root用户远程登录权限: 想myuser使用mypasswo ...

  9. 如何清除浮动(float)所带来的影响

    清除浮动(float) 1.定义和用法 在w3c中给了浮动这样的定义. "float 属性定义元素在哪个方向浮动.以往这个属性总应用于图像,使文本围绕在图像周围,不过在 CSS 中,任何元素 ...

  10. finally知识讲解

    finally语句一定会执行吗,很多人认为一定会,其实未必,只有与 finally 相对应的 try 语句块得到执行的情况下,finally 语句块才会执行.假如在try语句之前执行了return操作 ...