题目描述

题面

一个长度为 \(n\) 的大数,用 \(S_1S_2S_3 \cdots S_n\)表示,其中 \(S_i\) 表示数的第 \(i\) 位, \(S_1\) 是数的最高位。告诉你一些限制条件,每个条件表示为四个数,\(l_1,r_1,l_2,r_2\),即两个长度相同的区间,表示子串 \(S_{l_1}S_{l_1+1}S_{l_1+2} \cdots S_{r_1}\)\(S_{l_2}S_{l_2+1}S_{l_2+2} \cdots S_{r_2}\)完全相同。

比如 \(n=6\) 时,某限制条件 \(l_1=1,r_1=3,l_2=4,r_2=6\) ,那么 \(123123\)\(351351\) 均满足条件,但是 \(12012\)\(131141\) 不满足条件,前者数的长度不为 \(6\) ,后者第二位与第五位不同。问满足以上所有条件的数有多少个。

数据范围

\(1\le n\le 10^5\)\(1\le m\le 10^5\) ,$ 1\le li1,ri1,li2,ri2 \le n $ ;并且保证 $ r1_{i}-l1_{i}=r2_{i}-l2_{i} $ 。

solution

这题难想在用 ST 表优化并查集的合并过程(还是第一次见呢),感觉很好的例题,所以就跑来写题解了 /cy

\(f_{i, j}\) 表示以 \(i\) 为左端点,区间 \([i, j]\) 其中 \(i\) 已经完成合并的 \(i\) 的祖先(还是具体看代码理解吧 /kk)

合并就类似 ST 表预处理的方式正常合并就好了。

复杂度:\(O(nlog^2n)\)

code

/*Work by:Ariel_*/
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 5;
const int mod = 1e9 + 7;
int read() {
  int x = 0, f = 1; char c = getchar();
  while(c < '0' || c > '9'){if (c == '-') f = -1;c = getchar();}
  while(c >= '0' && c <= '9') {x = x * 10 + c - '0';c = getchar();}
  return x * f;
}
int N, M, f[MAXN][25];
int find(int x, int y) {return f[x][y] == x ? f[x][y] : f[x][y] = find(f[x][y], y);}
void merge(int x, int y, int len) {
  int fx = find(f[x][len], len), fy = find(f[y][len], len);
  f[f[fx][len]][len] = fy;
}
int main(){
  N = read(), M = read();
  for (int i = 1; i <= N; i++) 
    for (int j = 0; j <= 21; j++) f[i][j] = i;
  for (int i = 1; i <= M; i++) {
  	int l1 = read(), r1 = read(), l2 = read(), r2 = read();
  	int len = log2(r1 - l1 + 1);
	merge(l1, l2, len);
	l1 = r1 - (1 << len) + 1, l2 = r2 - (1 << len) + 1;
	merge(l1, l2, len); 
  }
  for (int len = 21; len >= 1; len--) {
  	 for (int i = 1; i + (1 << len) - 1 <= N; i++) {
  	     int fa = find(i, len);
		 if(fa == i) continue;
		 merge(i, fa, len - 1);
		 merge(i + (1 << (len - 1)), fa + (1 << (len - 1)), len - 1); 	
	  }
  }
  long long Ans = 0;
  for (int i = 1; i <= N; i++) {
  	 if(f[i][0] == i) {
  	   if(Ans == 0) Ans = 9;
	   else Ans = Ans * 10 % mod;	
	 } 
  }
  cout<<Ans;
  puts("");
  return 0;
}

原文地址:http://www.cnblogs.com/Dita/p/16914939.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性