• 刷题记录


    [APIO2011]方格染色

    有一种独特的角度,对于 (x, y ge 2) 的点对,从左上角到这个位置的矩形所有位置填满 (2 * 2) 的小正方形,发现除了四个角,剩下都被覆盖了偶数次。设小正方形数量奇偶性为 (a),那么就有结论 ((1, 1) ext{ xor } (x, 1) ext{ xor } (1, y) ext{ xor } (x, y) = a)。枚举 ((1,1)) 的值,然后就把这个关系转化为第一行第一列两个变量的关系,用扩展域并查集。对于在第一行第一列的点,如果他被固定,那么他所在联通块就不能活动,可以认为将其与 ((1, 1)) 建立关系。所以两方面是统一的,而题解没有说清楚。

    [APIO2008]免费道路

    (1) 边连成所有联通块后,需要必须的边数 (a) 将其连起来。
    三种无解:

    • 能放到一颗树里的边 (< K)
    • (a > K)
    • 图不联通

    剩下的情况,相当于添加 (K - a)(0) 边来代替 (1) 的作用,肯定可以做到,因为没有合并 (0) 边前他都合并起来了,所以有了他更行了。

    [APIO2009]会议中心

    这题教会我怎么快速求区间内最多不相交线段数。

    考虑把包含线段去掉,剩下的是左右端点递增的区间,这样每个区间有了唯一的后继,就可以做倍增了(选择第一个左端点大于自身右端点)

    [APIO2011]寻路

    关键是发现性质,肯定不会在没有出现过的沿着横纵坐标上走,因为这样肯定到不了终点。

    因此只要在离散化的点(有边的)上建图就好了,点边都是 ((N ^ 2)),每个点向最近的上下左右四个位置建边即可。

    [APIO2009]采油区域

    三个正方形可以把整个矩形恰好分成三个矩形,每个矩形求最大值即可。

    分类讨论 (6) 种分割方案。

    [NOI2008]假面舞会

    题解有问题,并不能找出所有的环。

    我迄今为止还不知道为啥这样可以找到所有环长 gcd。

    [NOI2016] 循环之美

    (frac{x}{y}) 相同的值只统计一次 (Rightarrow) 只统计 (x ⊥ y) 的点对。

    (frac{x}{y})(K) 进制下是纯循环小数 (Rightarrow) 模仿竖式计算,考虑纯循环的充要条件就是在不断除的过程中碰到相同的余数,即存在正整数 (t),满足 (x equiv xk^t mod y Leftrightarrow k^t equiv 1 mod y Leftrightarrow k ⊥ y)

    最后一步右推左,(t = varphi(y)) 就好了,左推右考虑 (gcd(y, k^t) ot= 1) 的情况他们的减法也必然是 ( ext{gcd}) 的倍数不可能是 (1)

    故 $$ ext{Ans} = displaystyle sum_{x=1}^n sum_{y=1}^m [x ⊥ y] [y ⊥ k] = displaystyle sum_{y=1}^m [y ⊥ k] sum_{x=1}^n sum_{d|x, d|y} mu(d) displaystyle = sum_{d=1}^{min(n,m)} mu(d) [d ⊥ k] lfloor frac{n}{d} floor sum_{y=1}^{lfloor frac{m}{d} floor} [y ⊥ k]$$

    这很类似一个数论分块的形式,设 (f(n, k) = displaystyle sum_{i=1}^{n} mu(i) [i ⊥ k], g(n, k) = displaystyle sum_{i=1}^{n} [i ⊥ k])

    那么 ( ext{Ans} = displaystyle sum_{d=1}^{min(n,m)} mu(d) [d ⊥ k] lfloor frac{n}{d} floor g(lfloor frac{m}{d} floor, k))

    只要能快速在关键点处 (约为 (sqrt{n}) 级别)的前缀和 (假设 (O(a))),那么就可以 (O(asqrt{n})) 做了。

    考虑 (f, g) 怎么求,第二维是 (1) 的话,后者就是 (n),前者可以杜教筛求出,注意用到的 (n) 必然是 (n, m) 除一个数下取整的数,因此是 (sqrt{n}) 级别,杜教筛 (O(n^{frac{2}{3}}))

    然后考虑先把 (K) 的平方因子去掉,互质性质不变,考虑从 (K) 里去掉一个素因子的影响:

    • (f(n, k) = f(n, k / p) + f(lfloor frac{n}{p} floor, k))

    • (g(n, k) = g(n, k / p) + g(lfloor frac{n}{p} floor, k / p))

    会用到的 (k) 大概是原来 (K) 的质因子级别(考虑这个质因子都选最小质因子),每次递推是 (O(1)),因此总复杂度大概是 (O(n^{frac{2}{3}} + sqrt{n} log k))

    #include <iostream>
    #include <cstdio>
    #include <map>
    #include <cstring>
    using namespace std;
    
    typedef long long LL;
    
    const int S = 1e7 + 1, T = 2005, INF = 0x3f3f3f3f;
    
    int primes[S], tot, fac[S], mu[S];
    
    bool st[S];
    
    int gcd(int a, int b) {
    	return b ? gcd(b, a % b) : a;
    }
    
    map<int, int> F[T], G[T], mu2;
    
    LL ans;
    
    LL f(int n, int k) {
    	if (n == 0) return 0;
    	if (n == 1) return 1;
    	if (F[k].count(n)) return F[k][n];
    	else if (k > 1) {
    		int p = fac[k];
    		return F[k][n] = (f(n, k / p) + f(n / p, k));
    	} else {
    		if (n < S) return mu[n];
    		int res = 1;
    		for (int l = 2, r, t; l <= n; l = r + 1) {
    			t = n / l, r = n / t;
    			res -= f(t, k) * (r - l + 1);
    		}
    		return F[k][n] = res;
    	}
    }
    
    LL g(int n, int k) {
    	if (n == 0) return 0;
    	if (G[k].count(n)) return G[k][n];
    	else if (k > 1) {
    		int p = fac[k];
    		return G[k][n] = (g(n, k / p) - g(n / p, k / p));
    	} else return n;
    }
    
    void init() {
    	for (int i = 1; i < S; i++) mu[i] = 1;
    	for (int i = 2; i < S; i++) {
    		if (!st[i]) primes[++tot] = i, mu[i] = -1, fac[i] = i;
    		for (int j = 1; primes[j] * i < S; j++) {
    			st[primes[j] * i] = true;
    			fac[primes[j] * i] = primes[j];
    			if (i % primes[j] == 0) {
    				mu[i * primes[j]] = 0;
    				break;
    			}
    			mu[i * primes[j]] = -mu[i];
    		}
    	}
    	for (int i = 2; i < S; i++) mu[i] += mu[i - 1];
    }
    
    int main() {
    	init();
    	int n, m, K; scanf("%d%d%d", &n, &m, &K);
    	for (int i = 2; i <= K; i++) {
    		while (K % i == 0 && (K / i) % i == 0) K /= i;
    	}
    	for (int l = 1, r, a, b; l <= min(n, m); l = r + 1) {
    		a = n / l, b = m / l, r = min(min(n, m), min(n / a, m / b));
    		ans += a * (f(r, K) - f(l - 1, K)) * g(b, K);
    	}
    	printf("%lld
    ", ans);
    	return 0;
    }
    

    [SDOI2018]旧试题

    草数学公式写的太累了。

    跟循环之美大致类似,要用到约数个数和的 trick。(d(i, j, k) = displaystyle sum_{x|i} sum_{y|j} sum_{z|k} [x ⊥ y] [x ⊥ z] [y ⊥ z])。这个可以扩展到 (n) 元,大致就是每个质因子独立,然后恰好出现的次数是对的。

    可以拿非平方因子数来建一颗数,这样每次增加一层的就是 (O(n sqrt{n}))

    #include <iostream>
    #include <cstdio>
    #include <unordered_map>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    using namespace std;
    
    typedef long long LL;
    
    const int S = 1e5 + 1, T = 1e5 + 1, INF = 0x3f3f3f3f, P = 1e9 + 7;
    
    int primes[S], tot, fac[S], mu[S], h[S], d[8], top[8], A[8][S * 20], B[8][S * 20];
    
    bool st[S], vis[S];
    
    int F[8][T], G[8][T];
    
    vector<int> e[S];
    
    int s[S], ans;
    int a, b, c; 
    
    int f(int n, int k) {
    	if (n == 0) return 0;
    	if (n == 1) return 1;
    	if (k == 0) return mu[n];
    	if (F[k][n] != -1) return F[k][n];
    	else {
    	    ++top[k];
    		A[k][top[k]] = k, B[k][top[k]] = n;
    		int p = fac[d[k]];
    		return F[k][n] = (f(n, k - 1) + f(n / p, k)) % P;
    	} 
    }
    
    void init() {
    	for (int i = 1; i < S; i++) mu[i] = 1;
    	for (int i = 2; i < S; i++) {
    		if (!st[i]) primes[++tot] = i, mu[i] = -1, fac[i] = i;
    		for (int j = 1; primes[j] * i < S; j++) {
    			st[primes[j] * i] = true;
    			fac[primes[j] * i] = primes[j];
    			if (i % primes[j] == 0) {
    				mu[i * primes[j]] = 0;
    				break;
    			}
    			mu[i * primes[j]] = -mu[i];
    		}
    	}
    	
    	for (int i = 2; i < S; i++) (mu[i] += mu[i - 1] + P) %= P;
    }
    
    
    int g(int n, int k) {
    	if (n == 0) return 0;
    	if (G[k][n] != -1) return G[k][n];
    	else if (k > 0) {
    	    ++top[k];
    		A[k][top[k]] = k, B[k][top[k]] = n;
    		int p = fac[d[k]];
    		return G[k][n] = ((LL)g(n, k - 1) - g(n / p, k - 1) + P) % P;
    	} else {
    		++top[k];
    		A[k][top[k]] = k, B[k][top[k]] = n;
    		int res = 0;
    		for (int l = 1, r, t; l <= n; l = r + 1) {
    			t = n / l, r = n / t;
    			res = (res + t * (r - l + 1ll)) % P;
    		}
    		return G[k][n] = res;
    	}
    }
    
    void dfs(int u, int dep) {
    	top[dep] = 0; int s = 0;
    	d[dep] = u;
    	for (int l = 1, r, t, v; l <= min(b, c); l = r + 1) {
    		t = b / l, v = c / l, r = min(min(b, c), min(b / t, c / v));
    		s = (s + ((LL)f(r, dep) - f(l - 1, dep) + P) * g(t, dep) % P * g(v, dep)) % P;
    	}
    	
    	h[u] = s;
    	for (int i = 0; i < e[u].size(); i++) {
    		int v = e[u][i];
    		dfs(v, dep + 1);
    	}
    	
    	for (int j = 1; j <= top[dep]; j++) 
    		F[A[dep][j]][B[dep][j]] = -1, G[A[dep][j]][B[dep][j]] = -1;
    }
    
    int main() {
    	memset(F, -1, sizeof F);
    	memset(G, -1, sizeof G);
    	init();
    	int T; scanf("%d", &T);
    	while (T--) {
    		scanf("%d%d%d", &a, &b, &c);
    		for (int i = 1; i <= a; i++) vis[i] = false, e[i].clear();
    		ans = 0;
    		
    		for (int i = 1; i <= a; i++) {
    			int s = 0; int x = i;
    			for (int j = 2; j * j <= x; j++)
    		 		while (x % j == 0 && (x / j) % j == 0) x /= j;
    			if (!vis[x] && fac[x] > 1) vis[x] = true,  e[x / fac[x]].push_back(x);
    			
    		}
    		
    		dfs(1, 0);
    		
    		for (int i = 1; i <= a; i++) {
    			int s = 0; int x = i;
    			for (int j = 2; j * j <= x; j++)
    		 		while (x % j == 0 && (x / j) % j == 0) x /= j;
    		 	ans = (ans + (LL)h[x] * (a / i)) % P;
    		}
    		
    		printf("%d
    ", ans);
    	}
    }
    
  • 相关阅读:
    Kafka:ZK+Kafka+Spark Streaming集群环境搭建(十四)定义一个avro schema使用comsumer发送avro字符流,producer接受avro字符流并解析
    Kafka:ZK+Kafka+Spark Streaming集群环境搭建(十三)kafka+spark streaming打包好的程序提交时提示虚拟内存不足(Container is running beyond virtual memory limits. Current usage: 119.5 MB of 1 GB physical memory used; 2.2 GB of 2.1 G)
    Kafka:ZK+Kafka+Spark Streaming集群环境搭建(十二)VMW安装四台CentOS,并实现本机与它们能交互,虚拟机内部实现可以上网。
    Hadoop:安装ftp over hdfs
    Kafka:ZK+Kafka+Spark Streaming集群环境搭建(十一)定制一个arvo格式文件发送到kafka的topic,通过Structured Streaming读取kafka的数据
    Hadoop:开发机运行spark程序,抛出异常:ERROR Shell: Failed to locate the winutils binary in the hadoop binary path
    自动化运维工具——ansible详解(一)
    缓存雪崩和缓存穿透问题解决方案
    Redis 和 Memcached 的区别
    mongo之 前后台创建索引 --noIndexBuildRetry
  • 原文地址:https://www.cnblogs.com/dmoransky/p/14075294.html
Copyright © 2020-2023  润新知