数学相关模板-基础
反素数
求1-n以内约数最多的数
#include <iostream>
int p[16] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53 };
unsigned long long n;
unsigned long long ans,
ans_num; // ans 为 n 以内的最大反素数(会持续更新),ans_sum 为
// ans的因子数。
// depth: 当前在枚举第几个素数
// temp: 当前因子数量为 num的时候的数值
// num: 当前因子数
// up:上一个素数的幂,这次应该小于等于这个幂次嘛
void dfs(int depth, unsigned long long temp, unsigned long long num, int up) {
if (depth >= 16 || temp > n) return;
if (num > ans_num) { // 更新答案
ans = temp;
ans_num = num;
}
if (num == ans_num && ans > temp) ans = temp; // 更新答案
for (int i = 1; i <= up; i++) {
if (temp * p[depth] > n)
break; // 剪枝:如果加一个这个乘数的结果比ans要大,则必不是最佳方案
dfs(depth + 1, temp *= p[depth], num * (i + 1),
i); // 取一个该乘数,进行对下一个乘数的搜索
}
return;
}
using std::cin;
using std::cout;
int main() {
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
cin >> n;
ans_num = 0;
dfs(0, 1, 1, 60);
cout << ans << " " << ans_num;
return 0;
}
(数,对应的约数个数)
- 1e5, 83160 128
- 1e7, 8648640 448
- 1e9, 735134400 1344
- 1e12, 963761198400 6720
[ABC248G] GCD cost on the tree
题目描述
给定一颗树有
的最大公约数(gcd)。
求所有简单路径的贡献之和,对
假设当前计算gcd为d的所有路径和长度,直接计算不好计算,我们可以计算所有d|x的路径长度和,然后再减掉d的倍数的影响即可。
因为1e5以内,约数最多的数只有128,因此每个数最多只会加入128次,那么我们对于每个d,我们完全可以将树建出来,然后利用统计sz计算每个点被经过多少次。
#include<bits/stdc++.h>
#define fo(i,a,b) for (ll (i)=(a);(i)<=(b);(i)++)
#define fd(i,b,a) for (ll (i)=(b);(i)>=(a);(i)--)
#define eb emplace_back
#define pi pair<ll,ll>
#define mk(x,y) make_pair((x),(y))
#define lc (o<<1)
#define rc ((o<<1)|1)
#define fi first
#define se second
using namespace std;
typedef long long ll;
const ll inf = 1ll << 60;
const int N = 5e5 + 10;
const ll mo = 998244353;
vector<int> tr[N];
ll n, a[N], x, y, f[N];
ll p[N], tot, v[N], num;
bool vis[N];
vector<int> t[N], d;
queue<int> q;
vector<int> e[N];
bool bz[N], in[N];
ll sz[N], g[N], sum, c[N], u[N], ans;
void work(int x, int pos) {
d.clear();
d.eb(1);
int z = v[x], l, r;
while (x != 1) {
z = v[x];
l = 0; r = d.size();
while (x % z == 0) {
x /= z;
fo(i, l, r - 1) d.eb(d[i] * z);
l = r; r = d.size();
}
}
for (auto x : d) t[x].eb(pos);
}
void ins(int x) {
q.push(x);
bz[x] = 1;
work(a[x], x);
}
void bfs() {
ins(1);
while (!q.empty()) {
int x = q.front(); q.pop();
for (int v : tr[x]) {
if (!bz[v]) {
f[v] = x;
ins(v);
}
}
}
}
void add(ll& x, ll y) {
x = (x + y) % mo;
}
void dg(int x) {
add(num, (sum - sz[x]) * sz[x] % mo + g[x]);
for (int v : e[x]) dg(v);
}
void dfs(int x) {
sz[x] = 0;
ll s = 0;
for (int v : e[x]) {
dfs(v);
sz[x] += sz[v];
s += sz[v] * sz[v];
}
g[x] = sz[x] + (sz[x] * sz[x] - s) / 2;
sz[x]++;
}
void solve()
{
fo(i, 2, N - 1) {
if (!vis[i]) {
p[++tot] = i;
v[i] = i;
}
fo(j, 1, tot) {
if (i * p[j] >= N) break;
vis[i * p[j]] = 1;
if (i % p[j] == 0) {
v[i * p[j]] = p[j];
break;
}
else v[i * p[j]] = p[j];
}
}
cin >> n;
fo(i, 1, n) cin >> a[i];
fo(i, 1, n - 1) {
cin >> x >> y;
tr[x].eb(y);
tr[y].eb(x);
}
bfs();
// for (auto x : t[1]) cout << x << "\n";
// cout << "\n";
// fo(i, 1, n)cout << f[i] << "\n";
fd(i, 1e5, 1) {
for (auto x : t[i]) {
in[x] = 1;
if (in[f[x]]) e[f[x]].eb(x);
}
ll z = 0;
for (auto x : t[i]) {
if (!in[f[x]]) {
dfs(x);
sum = sz[x];
num = 0;
dg(x);
add(z, num);
}
}
fo(j, 2, 1e5 / i) {
z = (z - u[i * j]) % mo;
}
u[i] = z;
add(ans, z* i% mo);
for (auto x : t[i]) {
e[x].clear();
in[x] = 0;
}
}
ans = (ans % mo + mo) % mo;
cout << ans;
}
int main()
{
// freopen("data.in", "r", stdin);
// freopen("data.out", "w", stdout);
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int T = 1;
// cin >> T;
while (T--)
{
solve();
}
return 0;
}
欧拉定理
扩展欧拉定理
当
#include<bits/stdc++.h>
#define fo(i,a,b) for (ll (i)=(a);(i)<=(b);(i)++)
#define fd(i,b,a) for (ll (i)=(b);(i)>=(a);(i)--)
#define lc (o<<1)
#define rc ((o<<1)|1)
#define mk(x,y) make_pair((x),(y))
#define eb emplace_back
#define A puts("Yes")
#define B puts("No")
#define fi first
#define se second
#define pi pair<ll,ll>
using namespace std;
typedef double db;
typedef long long ll;
typedef unsigned long long ull;
typedef long long i64;
//typedef __int128 i128;
const int inf=1e9;
const ll mo1=1e9+9;
const ll mo2=1e9+7;
const ll P=131;
const ll Q=13331;
//const ll mo=1e9+7;
const int N=1e5+5;
char ch;
ll a,m,b;
ll power(ll a,ll b){
ll t=1,y=a;
while (b) {
if (b&1) t=t*y%m;
y=y*y%m;
b/=2;
}
return t;
}
int main(){
// freopen("data.in","r",stdin);
// freopen("data.out","w",stdout);
scanf("%lld %lld",&a,&m);
a%=m;
ll t=m,phi=m;
for (ll i=2;i*i<=m;i++) {
if (t%i==0) {
phi=phi/i*(i-1);
while (t%i==0) t/=i;
}
}
if (t!=1) phi=phi/t*(t-1);
bool flag=0;
char ch;
for (ch=getchar();!('0'<=ch && ch<='9');ch=getchar());
for (;('0'<=ch && ch<='9');ch=getchar()) {
b=b*10+ch-'0';
if (b>=phi) {
b%=phi;
flag=1;
}
}
if (flag) printf("%lld\n",power(a,b+phi));
else printf("%lld\n",power(a,b));
return 0;
}
质因数分解
void work(int x){
e.clear();
e.push_back(1);
while (x!=1){
z=m[x];
l=0; r=e.size();
while (x%z==0) {
x/=z;
fo(i,l,r-1) e.push_back(e[i]*z);
l=r; r=e.size();
}
}
}
Pollard-Rho 算法
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int t;
long long max_factor, n;
long long gcd(long long a, long long b) {
if (b == 0) return a;
return gcd(b, a % b);
}
long long quick_pow(long long x, long long p, long long mod) { // 快速幂
long long ans = 1;
while (p) {
if (p & 1) ans = (__int128)ans * x % mod;
x = (__int128)x * x % mod;
p >>= 1;
}
return ans;
}
bool Miller_Rabin(long long p) { // 判断素数
if (p < 2) return 0;
if (p == 2) return 1;
if (p == 3) return 1;
long long d = p - 1, r = 0;
while (!(d & 1)) ++r, d >>= 1; // 将d处理为奇数
for (long long k = 0; k < 10; ++k) {
long long a = rand() % (p - 2) + 2;
long long x = quick_pow(a, d, p);
if (x == 1 || x == p - 1) continue;
for (int i = 0; i < r - 1; ++i) {
x = (__int128)x * x % p;
if (x == p - 1) break;
}
if (x != p - 1) return 0;
}
return 1;
}
long long Pollard_Rho(long long x) {
long long s = 0, t = 0;
long long c = (long long)rand() % (x - 1) + 1;
int step = 0, goal = 1;
long long val = 1;
for (goal = 1;; goal *= 2, s = t, val = 1) { // 倍增优化
for (step = 1; step <= goal; ++step) {
t = ((__int128)t * t + c) % x;
val = (__int128)val * abs(t - s) % x;
if ((step % 127) == 0) {
long long d = gcd(val, x);
if (d > 1) return d;
}
}
long long d = gcd(val, x);
if (d > 1) return d;
}
}
void fac(long long x) {
if (x <= max_factor || x < 2) return;
if (Miller_Rabin(x)) { // 如果x为质数
max_factor = max(max_factor, x); // 更新答案
return;
}
long long p = x;
while (p >= x) p = Pollard_Rho(x); // 使用该算法
while ((x % p) == 0) x /= p;
fac(x), fac(p); // 继续向下分解x和p
}
int main() {
scanf("%d", &t);
while (t--) {
srand((unsigned)time(NULL));
max_factor = 0;
scanf("%lld", &n);
fac(n);
if (max_factor == n) // 最大的质因数即自己
printf("Prime\n");
else
printf("%lld\n", max_factor);
}
return 0;
}
fwt相关
#include<bits/stdc++.h>
#define fo(i,a,b) for (ll (i)=(a);(i)<=(b);(i)++)
#define fd(i,b,a) for (ll (i)=(b);(i)>=(a);(i)--)
#define lc (o<<1)
#define rc ((o<<1)|1)
#define mk(x,y) make_pair((x),(y))
#define eb emplace_back
#define A puts("Yes")
#define B puts("No")
#define fi first
#define se second
#define pi pair<ll,ll>
using namespace std;
typedef double db;
typedef long long ll;
typedef unsigned long long ull;
typedef long long i64;
typedef unsigned int uint;
//typedef __int128 i128;
const int inf = 1e9;
const ll mo1 = 1e9 + 9;
const ll mo2 = 1e9 + 7;
const ll P = 131;
const ll Q = 13331;
const ll mo = 998244353;
const int N = 1 << 20;
ll inv2, a[N], b[N], n, aa[N], bb[N], c[N];
void add(ll& x, ll y) {
x = (x + y) % mo;
}
void Or(ll* a, ll type) {
for (ll x = 2;x <= n;x <<= 1) {
ll k = x >> 1;
for (ll i = 0;i < n;i += x) {
for (ll j = 0;j < k;j++) {
add(a[i + j + k], a[i + j] * type);
}
}
}
}
void And(ll* a, ll type) {
for (ll x = 2;x <= n;x <<= 1) {
ll k = x >> 1;
for (ll i = 0;i < n;i += x) {
for (ll j = 0;j < k;j++) {
add(a[i + j], a[i + j + k] * type);
}
}
}
}
void Xor(ll* a, ll type) {
for (ll x = 2;x <= n;x <<= 1) {
ll k = x >> 1;
for (ll i = 0;i < n;i += x) {
for (ll j = 0;j < k;j++) {
add(a[i + j], a[i + j + k] % mo);
a[i + j + k] = (a[i + j] - 2ll * a[i + j + k] % mo) % mo;
a[i + j] = a[i + j] * type % mo;
a[i + j + k] = a[i + j + k] * type % mo;
}
}
}
}
int main() {
// freopen("data.in","r",stdin);
// freopen("data.out","w",stdout);
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
inv2 = -(mo / 2);
inv2 = (inv2 % mo + mo) % mo;
cin >> n;
n = 1 << n;
fo(i, 0, n - 1) cin >> a[i];
fo(i, 0, n - 1) cin >> b[i];
fo(i, 0, n - 1) aa[i] = a[i], bb[i] = b[i];
Or(aa, 1); Or(bb, 1);
fo(i, 0, n - 1) c[i] = aa[i] * bb[i] % mo;
Or(c, -1);
fo(i, 0, n - 1) cout << (c[i] % mo + mo) % mo << " ";
cout << "\n";
fo(i, 0, n - 1) aa[i] = a[i], bb[i] = b[i];
And(aa, 1); And(bb, 1);
fo(i, 0, n - 1) c[i] = aa[i] * bb[i] % mo;
And(c, -1);
fo(i, 0, n - 1) cout << (c[i] % mo + mo) % mo << " ";
cout << "\n";
fo(i, 0, n - 1) aa[i] = a[i], bb[i] = b[i];
Xor(aa, 1); Xor(bb, 1);
fo(i, 0, n - 1) c[i] = aa[i] * bb[i] % mo;
Xor(c, inv2);
fo(i, 0, n - 1) cout << (c[i] % mo + mo) % mo << " ";
cout << "\n";
return 0;
}
[TJOI2011] 01矩阵
题目描述
首先预处理出哪些状态是合法的,假设这一行。的状态是s,那么能够由上一行转移来的t必定满足s|t=0,因此t是s补集中的子集,直接利用or卷积即可。
#include<bits/stdc++.h>
#define fo(i,a,b) for (ll (i)=(a);(i)<=(b);(i)++)
#define fd(i,b,a) for (ll (i)=(b);(i)>=(a);(i)--)
#define lc (o<<1)
#define rc ((o<<1)|1)
#define mk(x,y) make_pair((x),(y))
#define eb emplace_back
#define A puts("Yes")
#define B puts("No")
#define fi first
#define se second
#define pi pair<ll,ll>
using namespace std;
typedef double db;
typedef long long ll;
typedef unsigned long long ull;
typedef long long i64;
typedef unsigned int uint;
//typedef __int128 i128;
const int inf = 1e9;
const ll mo1 = 1e9 + 9;
const ll mo2 = 1e9 + 7;
const ll P = 131;
const ll Q = 13331;
const ll mo = 10007;
const int N = 1 << 20;
int c[300][300];
ll inv2, a[N], b[N], n, aa[N], bb[N], m, f[N], g[N], st[N], one[N], zero[N];
string s;
bool bz[N];
void add(ll& x, ll y) {
x = (x + y) % mo;
}
void Or(ll* a, ll type) {
for (ll x = 2;x <= n;x <<= 1) {
ll k = x >> 1;
for (ll i = 0;i < n;i += x) {
for (ll j = 0;j < k;j++) {
add(a[i + j + k], a[i + j] * type);
}
}
}
}
void And(ll* a, ll type) {
for (ll x = 2;x <= n;x <<= 1) {
ll k = x >> 1;
for (ll i = 0;i < n;i += x) {
for (ll j = 0;j < k;j++) {
add(a[i + j], a[i + j + k] * type);
}
}
}
}
void Xor(ll* a, ll type) {
for (ll x = 2;x <= n;x <<= 1) {
ll k = x >> 1;
for (ll i = 0;i < n;i += x) {
for (ll j = 0;j < k;j++) {
add(a[i + j], a[i + j + k] % mo);
a[i + j + k] = (a[i + j] - 2ll * a[i + j + k] % mo) % mo;
a[i + j] = a[i + j] * type % mo;
a[i + j + k] = a[i + j + k] * type % mo;
}
}
}
}
int main() {
// freopen("data.in","r",stdin);
// freopen("data.out","w",stdout);
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
inv2 = -(mo / 2);
inv2 = (inv2 % mo + mo) % mo;
cin >> n >> m;
fo(i, 1, n) {
cin >> s;
fo(j, 1, m) {
if (s[j - 1] == '.') c[i][j] = -1;
else c[i][j] = s[j - 1] - '0';
}
}
if (n > 15) {
fo(i, 1, n) fo(j, i + 1, n) swap(c[i][j], c[j][i]);
swap(n, m);
}
fo(j, 1, m) {
fo(i, 0, n - 1) {
if (c[i + 1][j] == 0) zero[j] |= (1 << i);
if (c[i + 1][j] == 1) one[j] |= (1 << i);
}
}
int k = n;
n = 1 << n;
fo(s, 0, n - 1) {
fo(i, 0, k - 2) {
if ((s & (1 << i)) && (s & (1 << (i + 1)))) bz[s] = 1;
}
}
f[0] = 1;
fo(i, 1, m) {
Or(f, 1);
fo(j, 0, n - 1) {
if (bz[j] || (j & zero[i]) || ((j & one[i]) != one[i])) g[j] = 0;
else g[j] = f[j ^ (n - 1)];
}
fo(j, 0, n - 1) f[j] = g[j];
}
ll ans = 0;
fo(j, 0, n - 1) add(ans, g[j]);
ans = (ans % mo + mo) % mo;
cout << ans;
return 0;
}
[HAOI2015] 按位或
题目描述
刚开始你有一个数字 |
,pascal 的 or
)操作。选择数字
需要利用min-max容斥,
考虑怎么求E(min(T)),假设选中T集合中的位置的概率为p,则
#include<bits/stdc++.h>
#define fo(i,a,b) for (ll (i)=(a);(i)<=(b);(i)++)
#define fd(i,b,a) for (ll (i)=(b);(i)>=(a);(i)--)
#define lc (o<<1)
#define rc ((o<<1)|1)
#define mk(x,y) make_pair((x),(y))
#define pi pair<ll,ll>
#define eb emplace_back
#define A puts("Yes")
#define B puts("No")
#define fi first
#define se second
using namespace std;
typedef double db;
typedef long long ll;
typedef unsigned long long ull;
typedef long long i64;
const ll inf = 1ll << 60;
const ll mo1 = 1e9 + 9;
const ll mo2 = 1e9 + 7;
const ll P = 131;
const ll Q = 13331;
const ll mo = 998244353;
const int N = 1 << 20;
const db eps = 1e-9;
ll n, st;
db a[N], p[N];
int main() {
// freopen("data.in", "r", stdin);
// freopen("data.out", "w", stdout);
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
db sum = 0;
cin >> n;
int st = (1 << n) - 1;
fo(i, 0, st) cin >> p[i], sum += p[i];
fo(j, 0, n - 1) fo(i, 0, st) {
if ((i >> j) & 1) p[i] += p[i ^ (1 << j)];
}
fo(i, 0, st) a[i] = sum - p[st ^ i];
bool flag = 1;
fo(i, 1, st) if (a[i] < eps) flag = 0;
if (!flag) {
cout << "INF";
return 0;
}
a[0] = 0;
fo(i, 1, st) {
int cnt = 0;
fo(j, 0, n - 1) if ((i >> j) & 1) ++cnt;
a[i] = 1.0 / a[i];
if (cnt % 2 == 0) a[i] = -a[i];
}
fo(j, 0, n - 1) fo(i, 0, st) {
if ((i >> j) & 1) a[i] += a[i ^ (1 << j)];
}
cout << fixed << setprecision(10) << a[st];
return 0;
}
excrt
【模板】扩展中国剩余定理(EXCRT)
题目描述
给定
#include<bits/stdc++.h>
#define fo(i,a,b) for (ll (i)=(a);(i)<=(b);(i)++)
#define fd(i,b,a) for (ll (i)=(b);(i)>=(a);(i)--)
#define lc (o<<1)
#define rc ((o<<1)|1)
#define mk(x,y) make_pair((x),(y))
#define eb emplace_back
#define A puts("Yes")
#define B puts("No")
#define fi first
#define se second
#define pi pair<ll,ll>
using namespace std;
typedef double db;
typedef long long ll;
typedef unsigned long long ull;
typedef long long i64;
typedef unsigned int uint;
//typedef __int128 i128;
const int inf = 1e9;
const ll mo1 = 1e9 + 9;
const ll mo2 = 1e9 + 7;
const ll P = 131;
const ll Q = 13331;
//const ll mo=1e9+7;
const int N = 2e5 + 5;
struct node {
ll r, m;
bool flag;
};
node a[N];
ll n;
ll gcd(ll a, ll b) {
if (!b) return a;
return gcd(b, a % b);
}
ll lcm(ll a, ll b) {
return a / gcd(a, b) * b;
}
void exgcd(ll a, ll b, ll& d, ll& x, ll& y) {
if (!b) {
d = a;
x = 1;
y = 0;
return;
}
exgcd(b, a % b, d, y, x);
y -= (a / b) * x;
}
ll mul(ll a, ll b, ll mod) {
a %= mod;
b %= mod;
ll t = 0;
while (b) {
if (b & 1) t = (t + a) % mod;
a = (a + a) % mod;
b /= 2;
}
return t;
}
node merge(node a, node b) {
ll r1, r2, m1, m2, x, y, d, mm, rr;
if (!a.flag) return (node) { 0, 0, 0 };
r1 = a.r; m1 = a.m;
r2 = b.r; m2 = b.m;
exgcd(m1, -m2, d, x, y);
if ((r2 - r1) % d) return (node) { 0, 0, 0 };
mm = lcm(m1, m2);
x = mul((r2 - r1) / d, x, mm);
rr = (mul(x, m1, mm) + r1 % mm) % mm;
return (node) { rr, mm, 1 };
}
int main() {
// freopen("data.in","r",stdin);
// freopen("data.out","w",stdout);
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin >> n;
fo(i, 1, n) cin >> a[i].m >> a[i].r, a[i].flag = 1;
node ans = a[1];
fo(i, 2, n) {
ans = merge(ans, a[i]);
}
ll r = ans.r, m = ans.m;
cout << (r % m + m) % m;
return 0;
}
矩阵乘法
#include<bits/stdc++.h>
#define fo(i,a,b) for (ll (i)=(a);(i)<=(b);(i)++)
#define fd(i,b,a) for (ll (i)=(b);(i)>=(a);(i)--)
#define eb emplace_back
using namespace std;
typedef long long ll;
const ll mo=998244353;
struct mat{
ll a[6][6];
mat(){
memset(a,0,sizeof(a));
}
};
mat operator* (mat a,mat b){
mat c;
fo(i,0,5) fo(j,0,5) fo(k,0,5) {
add(c.a[i][j], a.a[i][k]*b.a[k][j]%mo);
}
return c;
}
void power(ll b){
while (b) {
if (b&1) {
t=y*t;
}
y=y*y;
b/=2;
}
}
【模板】Dirichlet 前缀和
题目背景
模板题,无背景。
题目描述
给定一个长度为
现在你要求出一个长度为
由于某些神秘原因,这里的
类似于高维前缀和
#include<bits/stdc++.h>
#define fo(i,a,b) for (ll (i)=(a);(i)<=(b);(i)++)
#define fd(i,b,a) for (ll (i)=(b);(i)>=(a);(i)--)
#define eb emplace_back
#define pi pair<ll,ll>
#define mk(x,y) make_pair((x),(y))
#define lc (o<<1)
#define rc ((o<<1)|1)
//#define A puts("Yes")
//#define B puts("No")
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef double db;
const ll mo1=1e9+7;
const ll mo2=1e9+9;
const ll P=131;
const ll Q=13331;
const ll inf=1e9;
const int N=2e7+5;
#define uint unsigned int
uint seed;
uint a[N],ans;
bool bz[N];
int n;
inline uint getnext(){
seed^=seed<<13;
seed^=seed>>17;
seed^=seed<<5;
return seed;
}
int main() {
// freopen("data.in", "r", stdin);
// freopen("data.out", "w", stdout);
cin>>n>>seed;
fo(i,1,n) a[i]=getnext();
ans=a[1];
for (int i=2;i<=n;i++) {
if (!bz[i]) {
for (int j=2;j<=n/i;j++) {
bz[i*j]=1;
a[i*j]+=a[j];
}
}
ans^=a[i]+a[1];
}
cout<<ans;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现