【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\)。

代码:

#include<bits/stdc++.h>
#define ll long long
#define N 5005
#define M 1000005
#define D 205
#define ull unsigned long long using namespace std;
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;} int d,n,m;
struct road {int to,next;};
ll ans;
const int mod=10000007;
const ull p=2337;
ull pw[D];
ull g[N];
struct Hash {
int h[mod],cnt;
int size[N*N/5],nxt[N*N/5];
ull val[N*N/5];
void Insert(ull x) {
int v=x%mod;
for(int i=h[v];i;i=nxt[i]) {
if(val[i]==x) {
size[i]++;
ans+=2*size[i]-1;
return ;
}
}
val[++cnt]=x;
nxt[cnt]=h[v];
size[cnt]=1;
h[v]=cnt;
ans++;
}
void Del(ull x) {
int v=x%mod;
for(int i=h[v];i;i=nxt[i]) {
if(val[i]==x) {
ans-=2*size[i]-1;
size[i]--;
return ;
}
}
}
}ha; struct BCJ {
int id;
int f[N],size[N];
void Init() {for(int i=1;i<=n;i++) f[i]=i,size[i]=1;}
int Getf(int v) {return v==f[v]?v:f[v]=Getf(f[v]);}
road s[N<<1];
int h[N],cnt;
void add(int i,int j) {s[++cnt]=(road) {j,h[i]};h[i]=cnt;}
void dfs(int v,int fa) {
ha.Del(g[v]);
g[v]-=f[v]*pw[id-1];
f[v]=fa;
g[v]+=f[v]*pw[id-1];
ha.Insert(g[v]);
for(int i=h[v];i;i=s[i].next) {
int to=s[i].to;
dfs(to,fa);
}
}
void Merge(int a,int b) {
a=Getf(a),b=Getf(b);
if(a==b) return ;
if(size[a]>size[b]) swap(a,b);
add(b,a);
size[b]+=size[a];
dfs(a,b);
}
}T[D]; int main() {
d=Get(),n=Get(),m=Get();
for(int i=1;i<=d;i++) T[i].Init();
pw[0]=1;
for(int i=1;i<=d;i++) pw[i]=pw[i-1]*p; for(int i=1;i<=d;i++) T[i].id=i;
for(int i=1;i<=n;i++) {
for(int j=1;j<=d;j++) g[i]=g[i]*p+i;
ha.Insert(g[i]);
} int x,y,z;
for(int i=1;i<=m;i++) {
x=Get(),y=Get(),z=Get();
T[z].Merge(x,y);
cout<<ans<<"\n";
}
return 0;
}

【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. 阿里云redis映射到阿里云服务器

    参考文档:https://help.aliyun.com/document_detail/43850.html?spm=a2c4g.11186623.2.3.7yg9VH ECS Windows 篇 ...

  2. ASP.NET MVC 学习笔记-6.异步控制器

    1)         异步控制器的由来 对于IIS,它维护了一个.NET线程池来处理客户端请求,这个线程池称为工作线程池,其中的线程称为工作线程.当IIS接收到一个请求时,需要从工作线程池中唤醒一个工 ...

  3. 如何调用common.js

    第一步 页面需要引用此js 第二步 var loginJs = { //登录 goLogin: function () { var _userinfo = { name: "夏小沫" ...

  4. [android] 代码注册广播接收者&利用广播调用服务的方法

    利用广播调用服务里面的方法,间接的方式调用服务内部的方法,与现实中差不多,请媒体曝光 主界面里面 在界面创建的时候开启一下服务普通的startService()方法 发送一条广播出去 获取Intent ...

  5. IP是什么 DNS 域名与IP有什么不同

    IP地址是在网络上分配给每台计算机或网络设备的32位数字标识.在Internet上,每台计算机或网络设备的IP地址是全世界唯一的.IP地址的格式是 xxx.xxx.xxx.xxx,其中xxx是 0 到 ...

  6. What does operator “dot” (.) mean?

    Question: Given the code : A = [1 2 3; 3 2 1] B = A.^2 The output : B = 1 4 9 9 4 1 But if I do this ...

  7. Python 内置函数笔记

    其中有几个方法没怎么用过, 所以没整理到 Python内置函数 abs(a) 返回a的绝对值.该参数可以是整数或浮点数.如果参数是一个复数,则返回其大小 all(a) 如果元组.列表里面的所有元素都非 ...

  8. CSS字体样式属性

    font-size 字号大小 一般推荐使用相对长度(px ,em),不推荐使用绝对长度(in,cmm,mm,pt) font-family 字体 1.可以同时指定多个字体,中间用英文状态的逗号隔开,英 ...

  9. 2018-08-16 中文代码之Spring Boot添加基本日志

    之前中文代码之Spring Boot实现简单REST服务的演示服务不知为何中止. 新开issue: 演示服务中止 · Issue #2 · program-in-chinese/programming ...

  10. 小程序实践(二):swiper组件实现轮播图效果

    swiper组件类似于Android中的ViewPager,实现类似轮播图的效果,相对于Android的Viewpager,swiper实现起来更加方便,快捷. 效果图: 首先看下swiper支持的属 ...