首页 > 其他分享 >CodeForces 360D Levko and Sets

CodeForces 360D Levko and Sets

时间:2024-08-20 22:16:09浏览次数:12  
标签:typedef return int ll CodeForces maxn Levko Sets mod

洛谷传送门

CF 传送门

求出 \(p\) 的原根 \(g\),对每个 \(a_i\) 求出一个 \(x_i\) 表示 \(g^{x_i} \equiv a_i \pmod {p}\)(这部分可以 BSGS)。之后的表述中 \(a_i\) 指 \(x_i\)。那么集合生成方式相当于初始 \(c = 0\),每次让 \(c \gets (c + a_i b_j) \bmod (p - 1)\)。

根据裴蜀定理,若求出 \(x\) 为所有 \(b_j\) 的 \(\gcd\),每次操作相当于让 \(c \gets (c + x a_i) \bmod (p - 1)\)。

设 \(y_i = \gcd(x a_i, p - 1)\),那么第 \(i\) 个集合就是 \(\le p - 1\) 且为 \(y_i\) 倍数的所有数(包括 \(0\))。

现在要求集合并集大小。注意到 \(y_i\) 为 \(p - 1\) 的因数,于是对于 \(p - 1\) 的第 \(i\) 个因数 \(d_i\),设 \(f_i\) 为集合并集中与 \(p - 1\) 的 \(\gcd = i\) 的数的个数,再求出是否存在一个 \(y_i\) 使得 \(d_i \mid y_i\)。若不存在则 \(f_i = 0\);若存在则 \(f_i = \frac{p - 1}{d_i} - \sum\limits_{d_i \mid d_j} f_j\)。

那么答案就是 \(\sum f_i\)。

时间复杂度 \(O(\sqrt{np} + d(p - 1)^2)\)(前者是求 \(x_i\) 的复杂度;实际上后者的 \(O(d(p - 1)^2)\) 应该能做到 \(O(d(p - 1) \omega(p - 1))\))。

code
// Problem: D. Levko and Sets
// Contest: Codeforces - Codeforces Round 210 (Div. 1)
// URL: https://codeforces.com/problemset/problem/360/D
// Memory Limit: 256 MB
// Time Limit: 3000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mkp make_pair
#define mems(a, x) memset((a), (x), sizeof(a))

using namespace std;
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<ll, ll> pii;

const int maxn = 100100;
const int maxm = 3200000;

ll n, m, mod, a[maxn], b[maxn], d[maxn], tot, f[maxn];
bool vis[maxn];

inline ll qpow(ll b, ll p) {
	ll res = 1;
	while (p) {
		if (p & 1) {
			res = res * b % mod;
		}
		b = b * b % mod;
		p >>= 1;
	}
	return res;
}

inline bool check(int x) {
	vector<int> vc;
	int t = mod - 1;
	for (int i = 2; i * i <= t; ++i) {
		if (t % i == 0) {
			vc.pb(i);
			while (t % i == 0) {
				t /= i;
			}
		}
	}
	if (t > 1) {
		vc.pb(t);
	}
	for (int y : vc) {
		if (qpow(x, (mod - 1) / y) == 1) {
			return 0;
		}
	}
	return 1;
}

const int P = 333331;

struct HashTable {
	int hd[P + 3], len, to[maxm], nxt[maxm], val[maxm];
	
	inline void add(int x, int y) {
		int u = x % P;
		for (int i = hd[u]; i; i = nxt[i]) {
			if (to[i] == x) {
				return;
			}
		}
		to[++len] = x;
		val[len] = y;
		nxt[len] = hd[u];
		hd[u] = len;
	}
	
	inline int find(int x) {
		int u = x % P;
		for (int i = hd[u]; i; i = nxt[i]) {
			if (to[i] == x) {
				return val[i];
			}
		}
		return -1;
	}
} mp;

void solve() {
	scanf("%lld%lld%lld", &n, &m, &mod);
	if (mod == 3) {
		puts("1");
		return;
	}
	int g = 2;
	while (!check(g)) {
		++g;
	}
	for (int i = 1; i <= n; ++i) {
		scanf("%lld", &a[i]);
	}
	ll x = mod - 1;
	for (int i = 1; i <= m; ++i) {
		scanf("%lld", &b[i]);
		x = __gcd(x, b[i]);
	}
	ll pg = qpow(g, 316);
	for (int i = 0, j = 1; i <= 3170000; ++i, j = j * pg % mod) {
		mp.add(j, i);
	}
	for (int i = 1; i * i < mod; ++i) {
		if ((mod - 1) % i) {
			continue;
		}
		d[++tot] = i;
		if (i * i != (mod - 1)) {
			d[++tot] = (mod - 1) / i;
		}
	}
	sort(d + 1, d + tot + 1);
	for (int i = 1; i <= n; ++i) {
		int j = 2e9;
		for (int k = 0, p = a[i]; k <= 317; ++k, p = 1LL * p * g % mod) {
			int t = mp.find(p);
			if (t != -1 && t * 316 - k >= 0) {
				j = min(j, t * 316 - k);
			}
		}
		ll y = __gcd(x * j, mod - 1);
		int t = lower_bound(d + 1, d + tot + 1, y) - d;
		vis[t] = 1;
	}
	for (int i = 1; i <= tot; ++i) {
		if (vis[i]) {
			for (int j = i + 1; j <= tot; ++j) {
				if (d[j] % d[i] == 0) {
					vis[j] = 1;
				}
			}
		}
	}
	ll ans = 0;
	for (int i = tot; i; --i) {
		if (!vis[i]) {
			continue;
		}
		f[i] = (mod - 1) / d[i];
		for (int j = i + 1; j <= tot; ++j) {
			if (d[j] % d[i] == 0) {
				f[i] -= f[j];
			}
		}
		ans += f[i];
	}
	printf("%lld\n", ans);
}

int main() {
	int T = 1;
	// scanf("%d", &T);
	while (T--) {
		solve();
	}
	return 0;
}

标签:typedef,return,int,ll,CodeForces,maxn,Levko,Sets,mod
From: https://www.cnblogs.com/zltzlt-blog/p/18370426

相关文章

  • Educational Codeforces Round 168 (Rated for Div. 2) D题
    文章目录题目来源题意思路code题目来源D.MaximizetheRoot题意给定一棵n个点的数,根节点为1,每个点都有权值aia_i......
  • Codeforces Round 966 (Div. 3) (A~F)
    文章目录写在前面A-PrimaryTask思路codeB.SeatinginaBus思路codeC-NumericStringTemplate思路codeD-RightLeftWrong思路codeE-PhotoshootforGorillas思路codeF-ColorRowsandColumns思路codeCodeforcesRound966(Div.3)写在前面赛时写的......
  • Codeforces 169 Div2
    AClosestPoint由题意可得三个及以上的点无法插入新的点,只有两个点时可以插入但当两个点间隔为1时同样无法插入先判断,后输出就行#include<bits/stdc++.h>usingnamespacestd;constintN=50;intt,n;inta[N];intmain(){ cin>>t; while(t--){ cin>>n; for(i......
  • 自创CodeForcesHelperv1.0,解决CF太卡和跳题问题,代码持续更新!
    文章目录前言一、方法二、源代码三、使用方法四、效果展示总结前言对于OIers来说,Codeforces是一个很好的外国OJ。洛谷上确实收录了大部分CF的题,但是最近由于Codeforces的cloudflare加强了,所以洛谷的爬虫已经无法正确爬取提交记录的数据了,详见link。我......
  • Codeforces Round 894 (Div. 3) D
    题目:E.KolyaandMovieTheatre题目链接:https://codeforces.com/contest/1862/problem/E思路:主要用优先队列存放大于0的元素,然后除了第一个数据后的每m个数据就可以存放到记录数组里面,最后遍历找价值最大的点击查看代码#include<bits/stdc++.h>#defineintlonglongusing......
  • codeforces ECR169
    codeforcesECR169A#include<bits/stdc++.h>usingnamespacestd;constintmaxn=50;inta[maxn];voidsolve(){intn;cin>>n;for(inti=1;i<=n;i++)cin>>a[i];if(n==2){if((a[2]-a[1])!=1){......
  • CodeForces 1575F Finding Expected Value
    洛谷传送门CF传送门考虑单个序列如何求答案。考虑鞅与停时定理。定义一个局面的势能为\(\sum\limits_{i=0}^{K-1}f(b_i)\),其中\(f(x)\)是一个关于\(x\)的函数,\(b_i\)为\(i\)的出现次数。那么我们要构造\(f(x)\),使得每次操作,局面势能期望减少\(1\),那么期望步数......
  • Codeforces 232 B Table 题解 [ 蓝 ] [ 分组背包 ] [ 组合数学 ] [ 循环节 ]
    Codeforces232BTable。蒟蒻模拟赛上场切的一道蓝,非常难以置信我竟然能做蓝题。这题的数据范围初看还是比较坑的,\(10^{18}\)的值域很容易让人往矩阵加速那方面想。实际上在列出转移方程式后,我们发现状态是二维的,无法使用矩阵加速(或者说这样做很麻烦)。思路首先观察到每个边长......
  • Codeforces Round 966 (Div. 3) VP
    A.PrimaryTask枚举所有情况即可voidsolve(){ strings; cin>>s; if(s.substr(0,2)!="10"||s.size()<3||s[2]=='0'||(s.size()<4&&s[2]<'2')){ cout<<"NO\n"; } else{......
  • [CodeForces] F. Color Rows and Columns
    ProblemLink Basedoninitialobservation,itseemsthatgreedilypickthesmallestrow/columnlengthworks.Butthelastexampletestcaseoutputs35whilegreedygives36.  Howyoushouldgofromthere:1.checkifyourgreedyimplementationisco......