容斥原理 训练笔记

【RF】Receiver Function接收函数:从理论到实践的深度解析 本文深入解析地震学中的接收函数(Receiver Function, RF)技术,从理论原理到实践操作。文章将RF比作地球的“听诊器”,详细阐述了其通过反褶积剥离震源影响、揭示地下结构(如莫霍面)的核心机制,并提供了使用Python和rf库进行数据处理、计算、动校正与叠加的完整实战流程,同时探讨了其应用、局限性与常见问题的解决方案。 阅读详情

​

容斥原理

设S是一个有限集,A_1,A_2…A_n是S的n个子集,则

∣ S − ⋃ i = 1 n A i ∣ = ∑ i = 0 n ( − 1 ) i ∑ 1 ≤ j 1 < j 2 . . . < j i ≤ n ∣ ⋂ k = 1 i A j k ∣ |S-\bigcup_{i=1}^{n}A_i|=\sum_{i=0}^{n}(-1)^i\sum_{1\leq j_1< j_2...<j_i \leq n}|\bigcap_{k=1}^{i}A_{j_k}| ∣S−⋃i=1n​Ai​∣=∑i=0n​(−1)i∑1≤j1​<j2​...<ji​≤n​∣⋂k=1i​Ajk​​∣

基本应用:

m件不同的物品,分给n个人,要求每一个人至少分得一件物品,求不同的分配方案数

令 A i A_i Ai​表示第i个人没有物品, S S S表示 m m m个物品分给 n n n个人的总方案数

则 ∣ S − ⋃ i = 1 n A i ∣ = ∑ i = 0 n ( − 1 ) i ∑ 1 ≤ j 1 < j 2 . . . < j i ≤ n ∣ ⋂ k = 1 i A j k ∣ |S-\bigcup_{i=1}^{n}A_i|=\sum_{i=0}^{n}(-1)^i\sum_{1\leq j_1< j_2...<j_i\leq n}|\bigcap_{k=1}^{i}A_{j_k}| ∣S−⋃i=1n​Ai​∣=∑i=0n​(−1)i∑1≤j1​<j2​...<ji​≤n​∣⋂k=1i​Ajk​​∣

= ∑ i = 0 n ( − 1 ) i ( n i ) ( n − i ) m =\sum_{i=0}^{n}(-1)^i\binom{n}{i}(n-i)^m =∑i=0n​(−1)i(in​)(n−i)m

有 2 n 2n 2n个元素 a 1 , a 2 , . . . , a n a_1,a_2, ...,a_n a1​,a2​,...,an​ 和 b 1 , b 2 , . . . , b n b_1,b_2, ...,b_n b1​,b2​,...,bn​,求有多少个它们的全排列,满足任意的

1 ≤ i ≤ n 1 \leq i \leq n 1≤i≤n, a i a_i ai​ 和 b i b_i bi​ 都不相邻。

同样的,令 A i A_i Ai​表示 a i a_i ai​和 b i b_i bi​相邻,

则 ∣ S − ⋃ i = 1 n A i ∣ = ∑ i = 0 n ( − 1 ) i ∑ 1 ≤ j 1 < j 2 . . . j i ≤ n ∣ ⋂ k = 1 i A j k ∣ |S-\bigcup_{i=1}^{n}A_i|=\sum_{i=0}^{n}(-1)^i\sum_{1\leq j_1< j_2...j_i \leq n}|\bigcap_{k=1}^{i}A_{j_k}| ∣S−⋃i=1n​Ai​∣=∑i=0n​(−1)i∑1≤j1​<j2​...ji​≤n​∣⋂k=1i​Ajk​​∣
= ∑ i = 0 n ( − 1 ) i ( n i ) ∣ 有 i 对相邻的方案数 ∣ =\sum_{i=0}^{n}(-1)^i\binom{n}{i}|有i对相邻的方案数| =∑i=0n​(−1)i(in​)∣有i对相邻的方案数∣
= ∑ i = 0 n ( − 1 ) i ( n i ) 2 i ∗ ( 2 n − i ) ! =\sum_{i=0}^{n}(-1)^i\binom{n}{i}2^i*(2n-i)! =∑i=0n​(−1)i(in​)2i∗(2n−i)!

有了以上基本常识就可以上大招了

例题

CF449D

大意:
给出一个长度为n的序列 a 1 , a 2 . . . a n a_1,a_2...a_n a1​,a2​...an​。求从中选择一个非空子集使得他们的按位与之和等于0的方案数

思路:
不考虑复杂度的话我们有一个非常套路的容斥做法。考虑性质Ai表示子集与之后第i位为1,那么我们的答案其实就是
∣ Ω − A 1 ⋃ A 2 . . . ⋃ A 20 ∣ = ∑ i = 0 20 ( − 1 ) i ∑ 1 ≤ j 1 < j 2 . . . < j i ≤ 20 ∣ A j 1 ⋃ A j 2 . . . A j i ∣ |\Omega -A_1\bigcup A_2...\bigcup A_{20}|=\sum_{i=0}^{20}(-1)^i\sum_{1\leq j_1 < j_2...<j_i \leq 20 }|A_{j_1}\bigcup A_{j_2}...A_{j_i}| ∣Ω−A1​⋃A2​...⋃A20​∣=∑i=020​(−1)i∑1≤j1​<j2​...<ji​≤20​∣Aj1​​⋃Aj2​​...Aji​​∣
其中||符号就表示集合的大小

显然就可以状压枚举,这样的时间复杂度是 O ( n ∗ 1 e 6 ) O(n*1e6) O(n∗1e6),考虑优化。

注意到对于 ∣ A j 1 ⋃ A j 2 . . . A j i ∣ |A_{j_1}\bigcup A_{j_2}...A_{j_i}| ∣Aj1​​⋃Aj2​​...Aji​​∣,我们记满足对应所有性质的元素的个数为k,则该集合的大小就是 2 k − 1 2^k-1 2k−1,那么什么元素会满足这些性质呢?就是二进制为其超集的元素呗,其价值就是1.

所以我们只要做一遍超集后缀和即可,时间复杂度来到 O ( 20 ∗ 1 e 6 ) O(20*1e6) O(20∗1e6)

code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
const ll N=1e5+10;
const ll mod=1e9+7;
ll n,cnt=0,a;
ll mas[N];
ll up=20;
ll vis[30];
ll dp[(1<<20)+10];
ll ksm(ll x,ll y)
{
    ll ans=1;
    while(y)
    {
        if(y&1) ans=ans*x%mod;
        x=x*x%mod;
        y>>=1;
    }
    return ans;
}
ll gt()
{
    ll tot=0;
    ll fl;
    for(int i=1;i<=n;++i)
    {
        fl=1;
        for(int j=0;j<up;++j)
        {
            if(!vis[j]) continue;
            if((mas[i]&(1<<j))==0)
            {
                fl=0;
                break;
            }
        }
        if(fl) tot++;
    }

    return ((ksm(2,tot)-1)%mod+mod)%mod;
}
void solve()
{
    cin>>n;
    for(int i=1;i<=n;++i) cin>>a,dp[a]++;
    for(int j=0;j<up;++j)
    {
        for(int i=0;i<(1<<up);++i)
        {
            if((i&(1<<j))==0) dp[i]+=dp[i^(1<<j)];
        }
    }
    ll ans=0;
    for(int s=0;s<(1<<up);++s)
    {
        cnt=0;
        for(int i=0;i<up;++i) if(s&(1<<i)) cnt++;
        if(cnt%2) ans=((ans-ksm(2,dp[s])+1)%mod+mod)%mod;
        else ans=((ans+ksm(2,dp[s])-1)%mod+mod)%mod;
    }
    cout<<ans<<endl;
}
int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    solve();
    return 0;
}

CF1799G

大意:
在这里插入图片描述

思路:
个人认为这道题还是很顶的

题目有两个限制:每个人要得到 c i c_i ci​票,每个人不能投给自己组

然后这里就有一个很巧妙的转化:我们可以先将同一个组的人放在一起来看,这样就可以将第一个限制稍微弱化一些,最后我们再想办法处理组内的方案数

那么此时的问题如下:每一个组 i i i总共有 n u m i num_i numi​人,总共需要 f i f_i fi​票,组内的人不能投给自己组,求合法方案数

考虑生成函数处理

我们用 a i a_i ai​来表示第 i i i组的变元。那么对于第 i i i组的每一个人来说,它能投给除了自己组外的任河组,所以它的贡献是 a 1 + a 2 + . . . + a i − 1 + a i + 1 + . . . + a n a_1+a_2+...+a_{i-1}+a_{i+1}+...+a_n a1​+a2​+...+ai−1​+ai+1​+...+an​,我们可以简单记为 s − a i s-a_i s−ai​,其中s就表示 ∑ i = 1 n a i \sum_{i=1}^{n}a_i ∑i=1n​ai​

那么我们最后得到式子为 ( s − a 1 ) n u m 1 ( s − a 2 ) n u m 2 . . . ( s − a n ) n u m n (s-a_1)^{num_1}(s-a_2)^{num_2}...(s-a_n)^{num_n} (s−a1​)num1​(s−a2​)num2​...(s−an​)numn​,记为 S S S,而我们的答案显然就是 [ a 1 f 1 a 2 f 2 . . . a n f n ] ( S ) [a_1^{f_1}a_2^{f_2}...a_n^{f_n}](S) [a1f1​​a2f2​​...anfn​​](S).此时不难发现,对于 a i a_i ai​的指数,每一个s都可以提供1,而 ( s − a i ) n u m i (s-a_i)^{num_i} (s−ai​)numi​中的 − a i -a_i −ai​也可以提供不多于 n u m i num_i numi​的指数。

所以我们考虑每一个 a i a_i ai​的次数 det ⁡ i ( d e t i ≤ n u m i , d e t i ≤ f i ) \det_i(det_i \leq num_i,det_i \leq f_i) deti​(deti​≤numi​,deti​≤fi​),则每一个i有一个从 n u m i num_i numi​中选择 d e t i det_i deti​的方案数 ( n u m i d e t i ) \binom{num_i}{det_i} (deti​numi​​),并且 d e t i det_i deti​会提供 ( − 1 ) d e t i (-1)^{det_i} (−1)deti​的系数,然后剩下的所有指数都由 s s s提供,总共是 ∑ f i − ∑ d e t i = n − ∑ d e t i \sum f_i-\sum det_i=n-\sum det_i ∑fi​−∑deti​=n−∑deti​,要分成若干堆,第i堆有 f i − d e t i f_i-det_i fi​−deti​个,所以其实是一个可重集,不同组之间是相乘的关系,那么最终的答案其实就是
a n s = ∑ d e t i ≤ f i ( − 1 ) ∑ d e t i ∏ ( ( n u m i d e t i ) ) ( ( n − ∑ d e t i ) ! ( f 1 − d e t 1 ) ! ( f 2 − d e t 2 ) ! . . . ( f n − d e t n ) ! ) ans=\sum_{det_i\leq f_i}(-1)^{\sum det_i}\prod (\binom{num_i}{det_i})\binom{(n-\sum det_i)!}{(f_1-det_1)!(f_2-det_2)!...(f_n-det_n)!} ans=deti​≤fi​∑​(−1)∑deti​∏((deti​numi​​))((f1​−det1​)!(f2​−det2​)!...(fn​−detn​)!(n−∑deti​)!​)
= ∏ n u m i ∗ ∑ d e t i ≤ f i ( − 1 ) ∑ d e t i ( n − ∑ d e t i ) ! ∏ d e t i ! ( n u m i − d e t i ) ! ( f i − d e t i ) ! =\prod num_i *\sum_{det_i\leq f_i}(-1)^{\sum det_i}\frac{(n-\sum det_i)!}{\prod det_i!(num_i-det_i)!(f_i-det_i)!} =∏numi​∗deti​≤fi​∑​(−1)∑deti​∏deti​!(numi​−deti​)!(fi​−deti​)!(n−∑deti​)!​

那么其实n只有200,所以我们可以比较轻松地来得到这个式子的结果

考虑枚举 ∑ d e t i \sum det_i ∑deti​,我们记为 d d d,那么再记一个 d p i , j dp_{i,j} dpi,j​表示当前处理到了第i组, ∑ x ≤ i d e t i = j \sum_{x \leq i}det_i=j ∑x≤i​deti​=j,显然只要在过程中枚举合法的 d e t i det_i deti​就能完成这个dp了,外层枚举d,内层枚举i,j,最内层枚举 d e t i det_i deti​,乍一看时间复杂度好像是 O ( n 4 ) O(n^4) O(n4),但是因为 d e t i ≤ n u m i det_i \leq num_i deti​≤numi​,而 ∑ n u m i = n \sum num_i=n ∑numi​=n,所以实际复杂度只有 O ( n 3 ) O(n^3) O(n3)

这样我们就完成了组与组之间的关系。考虑组内部的票数分配, n u m i num_i numi​个人,每一个人需要 c i c_i ci​票,总共 ∑ c i = f i \sum c_i=f_i ∑ci​=fi​票,所以这其实还是一个多重集,那么我们只要乘上系数 f i ! ∏ c i ! \frac{f_i!}{\prod c_i!} ∏ci​!fi​!​即可

推推式子还是有点累的~

code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
const ll N=210;
const ll mod=998244353;
ll n;
ll f[N],t[N],c[N],num[N];//每一组的总期望票数,组别,个人期望票数,每组人数
ll dp[N][N];
ll ksm(ll x,ll y)
{
    ll ans=1;
    while(y)
    {
        if(y&1) ans=ans*x%mod;
        x=x*x%mod;
        y>>=1;
    }
    return ans;
}
ll inv(ll x)
{
    return ksm(x,mod-2);
}
ll p[N],pp[N];
void init(ll n)
{
    p[0]=1;
    for(ll i=1;i<=n;++i) p[i]=p[i-1]*i%mod;
    pp[n]=inv(p[n]);
    for(int i=n-1;i>=0;--i) pp[i]=pp[i+1]*(i+1)%mod;

}
void solve()
{
    init(200);
    // for(int i=1;i<=10;++i) cout<<p[i]<<" "<<pp[i]<<endl;
    cin>>n;
    for(int i=1;i<=n;++i) cin>>c[i];//期望票数
    for(int i=1;i<=n;++i) cin>>t[i],f[t[i]]+=c[i];
    for(int i=1;i<=n;++i) num[t[i]]++;
    ll ans=1,sum=0;
    for(int i=1;i<=n;++i) ans=ans*p[num[i]]%mod;
    ////
    for(int d=0;d<=n;++d)//det_i之和
    {
        for(int i=1;i<=n;++i) for(int j=0;j<=n;++j) dp[i][j]=0;
        dp[0][0]=p[n-d];

        for(int i=1;i<=n;++i)
        {
            //当前枚举到第i组
            for(int j=0;j<=d;++j)//到第i个人位置det_i的总和为j
            {
                for(int k=0;k<=min(f[i],num[i])&&k<=j;++k)//det_i=k
                {
                    ll det=pp[k]*pp[num[i]-k]%mod*pp[f[i]-k]%mod;
                    dp[i][j]=(dp[i][j]+det*dp[i-1][j-k]%mod)%mod;
                }
            }
        }
        if((d%2)==0) sum=(sum+ans*dp[n][d]%mod)%mod;
        else sum=((sum-ans*dp[n][d]%mod)%mod+mod)%mod;
    }
    for(int i=1;i<=n;++i)//组内多重集
    {
        sum=sum*p[f[i]]%mod*pp[c[i]]%mod;
    }
    cout<<sum<<endl;
}
int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    solve();
    return 0;
}

http://acm.hdu.edu.cn/contest/problem?cid=1102&pid=1011
23HDU 09K Cargo
大意:

n家店,每家店卖一种商品,总共有m种商品在卖。k次操作,每次随机选择一家店并且买下对应种类的商品。对于每一种商品i,记ci为售卖该种商品的店数,如果k次操作手里刚好有ci种i商品,且分别来自不同的店,则该商品合法。问k次操作之后所有种类的商品都不合法的方案数%998244353

n , m ≤ 1 e 5 , k < 998244353 n,m\leq 1e5,k<998244353 n,m≤1e5,k<998244353

思路:

可能数据范围并不是很支持直接容斥,但是可以发现基本上就是容斥的样子,所以试试看优化容斥。

令 A i A_i Ai​表示第种商品合法的方案数,

则 ∣ S − ⋃ i = 1 m A i ∣ = ∑ i = 0 m ( − 1 ) i ∑ 1 ≤ j 1 < j 2 . . . j i ∣ ⋂ k = 1 i A j k ∣ |S-\bigcup_{i=1}^{m}A_i|=\sum_{i=0}^{m}(-1)^i\sum_{1\leq j_1< j_2...j_i}|\bigcap_{k=1}^{i}A_{j_k}| ∣S−⋃i=1m​Ai​∣=∑i=0m​(−1)i∑1≤j1​<j2​...ji​​∣⋂k=1i​Ajk​​∣

只考虑 A i A_i Ai​,方案数为 A n c i ( n − c i ) k − c i A_{n}^{c_i}(n-c_i)^{k-c_i} Anci​​(n−ci​)k−ci​,意义显然。多个 A i A_i Ai​取交的话,方案数就是 A n ∑ c i ( n − ∑ c i ) k − ∑ c i A_{n}^{\sum c_i}(n-\sum c_i)^{k-\sum c_i} An∑ci​​(n−∑ci​)k−∑ci​

发现这个方案数只与 ∑ c i \sum c_i ∑ci​有关,而与顺序,某一个具体值无关,所以我们可以改变一下思路,转为枚举 ∑ c i \sum c_i ∑ci​

具体来说,对于每一个 ∑ c i = j \sum c_i=j ∑ci​=j,它的贡献就是用偶数个 c i c_i ci​累加得到j的方案数减去用奇数个 c i c_i ci​累加得到j的方案数,(这一步其实就是容斥原理公式的转化)

既然如此,我们考虑生成函数 1 − x c i 1-x^{c_i} 1−xci​,表示对于每一个 c i c_i ci​,取一个数得到和为 c i c_i ci​的方案数为-1,这是因为1是一个奇数,那么显然,在 ∏ ( 1 − x c i ) \prod (1-x^{c_i}) ∏(1−xci​)中,如果某一个指数是由偶数个数累加得到的,其系数自然会是正数,奇数同理。由此该生成函数就满足了我们的条件,我们只要对每一项 [ x j ] ( ∏ ( 1 − x c i ) ) [x_j](\prod (1-x^{c_i})) [xj​](∏(1−xci​))乘上对应的方案数系数 A n ∑ c i ( n − ∑ c i ) k − ∑ c i A_{n}^{\sum c_i}(n-\sum c_i)^{k-\sum c_i} An∑ci​​(n−∑ci​)k−∑ci​即可.

个人感觉这种题目应该还是有点套路可循的,因为如果数据范围小一点的话,就是明显显的容斥,然后找到性质用生成函数来优化就不是那么难想到的了

code

#include <map>
#include <set>
#include <array>
#include <cmath>
#include <queue>
#include <stack>
#include <tuple>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <random>
#include <string>
#include <vector>
#include <cassert>
#include <cstring>
#include <iomanip>
#include <limits.h>
#include <iostream>
#include <algorithm>
#include <functional>
#include <unordered_map>
using namespace std;

#define N maxn
#define db double
#define il inline
#define fir first
#define sec second
#define eps (1e-8)
#define pb push_back
#define ll long long
#define mkp make_pair
#define eb emplace_back
#define pii pair<int, int>
#define lowbit(a) (a & (-a))
#define SZ(a) ((int)a.size())
#define ull unsigned long long
#define all(a) a.begin(), a.end()
#define split cout << "=========\n";
#define GG { cout << "NO\n"; return; }
#define pll pair<long long, long long>
#define equals(a, b) (fabs((a) - (b)) < eps)

constexpr int ON = 0;
constexpr int CW = -1;
constexpr int CCW = 1;
constexpr int BACK = 2;
constexpr int FRONT = -2;
const db pi = acos(-1.000);
constexpr int maxn = 2e5 + 50;
constexpr int INF = 0x3f3f3f3f;
constexpr ll LINF =  0x3f3f3f3f3f3f3f3f;
constexpr int mod = 998244353; /* 1e9 + 7 */
constexpr int dir[8][2] = {-1, 0, -1, 1, 0, 1, 1, 1, 1, 0, 1, -1, 0, -1, -1, -1};

mt19937_64 rnd(random_device {}());
uniform_int_distribution<ull> dist(0, ULLONG_MAX);//use dist(rnd)

bool BEGIN;
ll qpow(ll x,ll y)
{
    ll ans=1;
    while(y)
    {
        if(y&1) ans=ans*x%mod;
        x=x*x%mod;
        y>>=1;
    }
    return ans;
}

namespace Poly
{
    #define mul(x, y) (1ll * x * y >= mod ? 1ll * x * y % mod : 1ll * x * y)
    #define minus(x, y) (1ll * x - y < 0 ? 1ll * x - y + mod : 1ll * x - y)
    #define plus(x, y) (1ll * x + y >= mod ? 1ll * x + y - mod : 1ll * x + y)//上面其实没用到
    #define ck(x) (x >= mod ? x - mod : x)//取模运算太慢了

    typedef vector<int> poly;
    const int G = 3;//根据具体的模数而定,原根可不一定不一样!!!
    //一般模数的原根为 2 3 5 7 10 6
    const int inv_G = qpow(G, mod - 2),tt = 22;
    int deer[2][tt][(1 << tt)];
    vector<int>RR(1 << (tt + 1), 0),inv(1 << tt, 0);

    void init(const int t) {//预处理出来NTT里需要的w和wn,砍掉了一个log的时间
        assert(t < tt);//一定要注意!!
        for(int p = 1; p <= t; ++ p) {
            int buf1 = qpow(G, (mod - 1) / (1 << p));
            int buf0 = qpow(inv_G, (mod - 1) / (1 << p));
            deer[0][p][0] = deer[1][p][0] = 1;
            for(int i = 1; i < (1 << p); ++ i) {
                deer[0][p][i] = 1ll * deer[0][p][i - 1] * buf0 % mod;//逆
                deer[1][p][i] = 1ll * deer[1][p][i - 1] * buf1 % mod;
            }
        }
        inv[1] = 1;
        for(int i = 2; i <= (1 << t); ++ i)
            inv[i] = 1ll * inv[mod % i] * (mod - mod / i) % mod;
    }

    int NTT_init(int n) {//快速数论变换预处理
        int limit = 1, L = 0;
        while(limit <= n) limit <<= 1, L ++ ;
        assert(L < tt);
        assert(limit < 1 << (tt + 1));
        for(int i = 0; i < limit; ++ i)
            RR[i] = (RR[i >> 1] >> 1) | ((i & 1) << (L - 1));
        return limit;
    }

    void NTT(poly &A, bool type, int limit) {//快速数论变换
        A.resize(limit);
        for(int i = 0; i < limit; ++ i)
            if(i < RR[i])
                swap(A[i], A[RR[i]]);
        for(int mid = 2, j = 1; mid <= limit; mid <<= 1, ++ j) {
            int len = mid >> 1;
            for(int pos = 0; pos < limit; pos += mid) {
//                auto wn = deer[type][j].begin();
                for(int i = pos, p = 0; i < pos + len; ++ i, ++ p) {
                    int tmp = 1ll * deer[type][j][p] * A[i + len] % mod;
                    A[i + len] = ck(A[i] - tmp + mod);
                    A[i] = ck(A[i] + tmp);
                }
            }
        }
        if(type == 0) {
            for(int i = 0; i < limit; ++ i)
                A[i] = 1ll * A[i] * inv[limit] % mod;
        }
    }

    poly poly_mul(poly A, poly B) {//多项式乘法
        int deg = A.size() + B.size() - 1;
        int limit = NTT_init(deg);
        poly C(limit);
        NTT(A, 1, limit);
        NTT(B, 1, limit);
        for(int i = 0; i < limit; ++ i)
            C[i] = 1ll * A[i] * B[i] % mod;
        NTT(C, 0, limit);
        C.resize(deg);
        return C;
    }

    poly poly_inv(poly &f, int deg) {//多项式求逆 deg<f.szie()
        if(deg == 1)
            return poly(1, qpow(f[0], mod - 2));

        poly A(f.begin(), f.begin() + deg);
        poly B = poly_inv(f, (deg + 1) >> 1);
        int limit = NTT_init(deg << 1);
        NTT(A, 1, limit), NTT(B, 1, limit);
        for(int i = 0; i < limit; ++ i)
            A[i] = B[i] * (2 - 1ll * A[i] * B[i] % mod + mod) % mod;
        NTT(A, 0, limit);
        A.resize(deg);
        return A;
    }

    poly poly_dev(poly f) {//多项式求导
        int n = f.size();
        for(int i = 1; i < n; ++ i) f[i - 1] = 1ll * f[i] * i % mod;
        if(n > 1)f.resize(n - 1);
        else f[0] = 0;
        return f.resize(n - 1), f;//求导整体左移,第0项不要
    }

    poly poly_idev(poly f) {//多项式求积分
        int n = f.size();
        for(int i = n - 1; i ; -- i) f[i] = 1ll * f[i - 1] * inv[i] % mod;
        return f[0] = 0, f;//积分整体右移,第0项默认为0
    }

    poly poly_ln(poly f, int deg) {//多项式求对数,第一项为1
        poly A = poly_idev(poly_mul(poly_dev(f), poly_inv(f, deg)));
        return A.resize(deg), A;
    }

    poly poly_exp(poly &f, int deg) {//多项式求指数,第一项为0
        if(deg == 1)
            return poly(1, 1);

        poly B = poly_exp(f, (deg + 1) >> 1);
        B.resize(deg);
        poly lnB = poly_ln(B, deg);
        for(int i = 0; i < deg; ++ i)
            lnB[i] = ck(f[i] - lnB[i] + mod);

        int limit = NTT_init(deg << 1);//n -> n^2
        NTT(B, 1, limit), NTT(lnB, 1, limit);
        for(int i = 0; i < limit; ++ i)
            B[i] = 1ll * B[i] * (1 + lnB[i]) % mod;
        NTT(B, 0, limit);
        B.resize(deg);
        return B;
    }

    poly poly_pow(poly f, int k) {//多项式快速幂,第一项得是1
        f = poly_ln(f, f.size());
        for(auto &x : f) x = 1ll * x * k % mod;
        return poly_exp(f, f.size());
    }
     poly poly_ksm(poly f, int k,int m) {//多项式快速幂,适用于初始只有几项,同时所有项都需要的情况,会比上面那个快一点
        poly res(1, 1);
        while(k){
            if(k & 1)
                {
                    res = poly_mul(res, f);
                    res.resize(m,0);
                }
            f = poly_mul(f, f);
            f.resize(m,0);
            k >>= 1;
        }
        return res;
    }



}

using Poly::poly;
using Poly::poly_pow;
using Poly::poly_ksm;
using Poly::poly_mul;
using Poly::poly_inv;
vector<ll> vt;
poly poly_f(int l,int r,int num)
    {
        if(l>r)
        {
            return poly(1,1);
        }
        if(l==r)
        {
            poly ans(vt[l]+1,0);
            ans[0]=1;
            ans[vt[l]]=(mod-1)%mod;
            return ans;
        }
        int mid=(l+r)>>1;
        poly f = poly_f(l,mid,num);
        poly g = poly_f(mid+1,r,num);
        f = poly_mul(f,g);
        // f.resize(num+1);
        return f;
    }

ll p[N],pp[N],C[N];
void init(ll n)
{
    p[0]=1;
    for(ll i=1;i<=n;++i) p[i]=p[i-1]*i%mod;
    pp[1]=1;
    for(ll i=2;i<=n;++i)
    {
        pp[i]=(mod-mod/i)*pp[mod%i]%mod;
    }
    // for(ll i=1;i<=n;++i) C[i]=C[i-1]*qpow(i,mod-2)%mod*(k-i+1)%mod;
}
void init2(ll n,ll k)
{
    C[0]=1;
    for(ll i=1;i<=n;++i) C[i]=C[i-1]*pp[i]%mod*(k-i+1)%mod;
    for(int i=1;i<=n;++i) C[i]=C[i]*p[i]%mod;
}

ll n,m,k;
map<ll,ll> num1;
void solve()
{
    num1.clear();
    cin>>n>>m>>k;
    init2(max(n,m),k);
    // for(int i=0;i<=10;++i) cout<<C[i]<<' ';
    //     cout<<endl;
    for(int i=1;i<=n;++i)
    {
        ll a;cin>>a;
        num1[a]++;
    }

    vt.clear();
    for(auto i:num1) vt.push_back(i.second);
    Poly::init(20);
    poly f=poly_f(0,vt.size()-1,n);


    ll ans=0;
    for(ll i=0;i<=min(n,k);++i)
    {
        // cout<<f[i]<<' '<<C[i]<<" "<<qpow(n-i,k-i)<<endl;
        ans=((ans+f[i]*C[i]%mod*qpow(n-i,k-i)%mod)%mod+mod)%mod;
    }
    cout<<ans*qpow(qpow(n,k),mod-2)%mod<<endl;
}

bool END;
signed main() {
    // cout << fixed << setprecision(10);
    ios::sync_with_stdio(false); cin.tie(nullptr);
    init(200000);
    int T; cin >> T; while (T--)
    solve();
    // cout << ((&END - & BEGIN) >> 21) << '\n';
    return 0;
}

18青岛G

大意:
给定一个由0,1,2组成的长度为n的数列,每次操作可以选择一个不含2的连续区间,将其中所有元素置为0.求恰好操作m次并且所有2都被消除的方案数, n ≤ 100 , m ≤ 1 0 9 n\leq 100,m\leq 10^9 n≤100,m≤109
思路:

不妨记一个不含1的连续区间是一个合法区间,那么仔细观察一下,对于一个长度为 l e n len len的合法区间,其操作的合法区间数是 ( l e n 2 ) + l e n = l e n ( l e n + 1 ) 2 \binom{len}{2}+len=\frac{len(len+1)}{2} (2len​)+len=2len(len+1)​,所以其答案就是 ( l e n ( l e n + 1 ) 2 ) m (\frac{len(len+1)}{2})^m (2len(len+1)​)m,是可以 O ( 1 ) O(1) O(1)计算得到的。这启示我们使用容斥来处理该问题 ,令 A i A_i Ai​表示从左往右数第 i i i个2没有消除的方案数,要求 a n s = ∣ S − A 1 ⋃ A 2 . . . ⋃ A x ∣ = ∑ i = 0 x ( − 1 ) i ∣ A j 1 ⋂ A j 2 . . . ⋂ A j i ∣ ans=|S-A_1\bigcup A_2...\bigcup A_x|=\sum_{i=0}^{x}(-1)^i|A_{j_1}\bigcap A_{j_2}...\bigcap A_{j_i}| ans=∣S−A1​⋃A2​...⋃Ax​∣=∑i=0x​(−1)i∣Aj1​​⋂Aj2​​...⋂Aji​​∣
但是显然数据范围并不允许我们直接暴力枚举,所以考虑dp优化(很常见的思路)。

显然 ∣ A j 1 ⋂ A j 2 . . . ⋂ A j i ∣ |A_{j_1}\bigcap A_{j_2}...\bigcap A_{j_i}| ∣Aj1​​⋂Aj2​​...⋂Aji​​∣前面的系数由 i i i,也就是不消除的2的个数决定,如果是奇数,系数就是-1,并且此时其他的2是不能消除的。所以不妨记 d p i , k , 0 / 1 dp_{i,k,0/1} dpi,k,0/1​表示前i个位置,合法操作区间数为k,总共有奇数/偶数个不能消除的2

为了方便计算,令 a 0 = a n + 1 = 1 a_0=a_{n+1}=1 a0​=an+1​=1,这不会影响结果

那么最终我们的答案就是 ∑ j = 1 n ( n + 1 ) / 2 ( d p n + 1 , j , 0 − d p n + 1 , j , 1 ) j m \sum_{j=1}^{n(n+1)/2}(dp_{n+1,j,0}-dp_{n+1,j,1})j^m ∑j=1n(n+1)/2​(dpn+1,j,0​−dpn+1,j,1​)jm,也就是枚举合法操作方案数为j的情况数

考虑转移,对于当前位置i,我们枚举上一个不消除的位置j, p r e i ≤ j < i , a j = 2 pre_i\leq j<i,a_j=2 prei​≤j<i,aj​=2,其中 p r e i pre_i prei​表示i之前的第一个1的位置,因为1是一定不能消除的。此时 d p i , k + ( i − j ) ( i − j + 1 ) 2 , 0 / 1 = ∑ j = p r e i i − 1 d p j , k , 1 / 0 \large dp_{i,k+\frac{(i-j)(i-j+1)}{2},0/1}=\sum_{j=pre_i}^{i-1}dp_{j,k,1/0} dpi,k+2(i−j)(i−j+1)​,0/1​=∑j=prei​i−1​dpj,k,1/0​

最后总体复杂度 O ( n 4 + l o g ( m ) ) O(n^4+log(m)) O(n4+log(m))

最后要特判一下1的个数,如果是奇数的话,显然改变了实际2的个数,所以答案要取负

ll dp[N][N*N][3];
ll n,m;
ll mas[N];
ll lim[N];//前i个点的最多的合法区间数
void solve()
{
    cin>>n>>m;
    for(int i=1;i<=n;++i) cin>>mas[i];
    mas[0]=mas[n+1]=1;
    dp[0][0][1]=1;dp[0][0][0]=0;lim[0]=0;
    ll pre=0;//上一个1的位置
    for(int i=1;i<=n+1;++i)
    {
        if(mas[i]==0) continue;
        lim[i]=lim[pre]+(i-pre)*(i-pre-1)/2;
        for (int j=0;j<=lim[i];++j) dp[i][j][0]=dp[i][j][1]=0;
        for(int j=pre;j<i;++j)
        {
            if(mas[j]==0) continue;
            ll add=(i-j)*(i-j-1)/2;
            for(int k=0;k<=lim[j];++k)
            {
                dp[i][k+add][0]=(dp[i][k+add][0]+dp[j][k][1])%mod;
                dp[i][k+add][1]=(dp[i][k+add][1]+dp[j][k][0])%mod;
            }
        }
        if(mas[i]==1) pre=i;
    }
    ll ans=0;
    for(int i=0;i<=lim[n+1];++i)
    {
        ll det=((dp[n+1][i][0]-dp[n+1][i][1])%mod+mod)%mod;
        ans=(ans+det*ksm(i,m)%mod)%mod;
    }

    ll cn=0;
    for(int i=1;i<=n;++i) if(mas[i]==1) cn++;
    if(cn%2) ans=(mod-ans)%mod;

    cout<<ans<<endl;
}

未完待续

​

边缘设备部署全攻略——ARM架构设备的OpenClaw优化(2026实测) 本文详细介绍了ARM架构设备上OpenClaw的部署与优化方案。针对边缘计算场景,文章系统分析了三类ARM设备:嵌入式设备(如Raspberry Pi 4、Jetson Nano)、工业设备(如BeagleBone、i.MX8M Plus)和服务器设备(如Marvell Armada、AWS Graviton3),并提供了详细的性能与功耗对比数据。在系统配置方面,重点推荐了Ubuntu ARM、Debian ARM和OpenWRT三种操作系统,包括内核版本、必备软件包和针对边缘环境的优化策略(如CPU频率调 阅读详情

相关推荐

UE5实战:如何用Georeference插件搞定百度地图坐标转换(附完整代码)

本文详细解析了在UE5中使用Georeference插件实现百度地图坐标转换的全流程,包括BD-09到UE内部坐标的转换算法、UTM投影配置及性能优化技巧。通过完整代码示例和实战案例,帮助开发者高效解决数字孪生项目中的地理坐标转换难题。

weixin_30955617的博客 94

容斥原理级笔记

容斥原理: | s1 ⋃ s2 ⋃ s3 …… ⋃ sn | = | s1 |+ | s2 | + …… | s3 | -| s1 ⋂ s2 | - …… +| s1 ⋂ s2 ⋂ s3 | + …… 应用一(基础): AcWing能被整除的数 思路: (1)容斥原理的直接应用。首先将所有能被其中任意一个p[i]整除的数的个数加上,再减去所有能被其中任意两个p[i]整除的数的个数,再加上所有能被其中任意三个p[i]整除的数的个数,一次类推...... (2)借助二进制代表是否需要满足次...

Galaxy_Su的博客 590

以太网测试用例(光模块线缆、网卡类设备、交换类设备)

LeCroy力科网络测试相关的测试用例分享:光模块/DAC/ACC/AEC/AOC测试,网卡类产品测试/GPU/DPU/SmartNIC,交换类产品测试。涉及物理层的FEC,SKEW,Tx/Rx Taps和Layer23层的网络性能测试/吞吐量延迟抖动丢包率背靠背性能,以及RDMA带状况的网络协议分析。同步提供400G高速的以太网的损伤,提供定量,可重复的负面压力测试环境。

专注有线以太网性能测试--丹麦信雅纳网络(Xena Networks) 1993

[学习笔记]min-max容斥

【Learning】min-max容斥以及推广 min-max容斥 就是max(a,b)=min(a)+min(b)-min(a,b) max(a,b,c)=a+b+c-min(a,b)-min(a,c)-min(b,c)+min(a,b,c) .... 为什么这样做? 有的时候min要好算很多 期望的线性 所以可以直接套期望 然后例题: [HAOI2015]按...

weixin_34413065的博客 345

基于Jira与Confluence的企业知识库AI助手构建实战

检索增强生成(RAG)技术通过结合信息检索与大型语言模型,有效解决了AI在专业领域知识不足的问题。其核心原理是将外部知识库(如企业文档)进行向量化存储,在用户提问时进行语义检索,并将相关上下文注入提示词中,从而生成精准、有据可依的回答。这一技术架构在工程实践中价值显著,它无需重新训练模型即可让AI掌握特定领域的专业知识,大幅提升了回答的准确性与实用性。典型的应用场景包括智能客服、企业内部知识问答以及代码辅助等。本文以开源项目`dev-kostiuk/jira-confluence-ai-context`为例

weixin_42520448的博客 366

Creo报许可证错误License request failed for feature的解决方案

有些朋友用了一段时间打开creo软件,出现icense request failed for feature”错误,这个是Creo许可证出现了问题,一般是许可证文件无效或是已过期,导致Creo软件通信出现故障,就会出现Creo License request failed for feature, Requsesting CreoPMA_SSQ ,Run ptcstatus.bat server status。第三步:键盘按win+R,在运行窗口里输入:cmd,然后点确定。第八步:点击系统,找到系统信息。

Q82556499的博客 3万+

容斥原理学习笔记

简单来说,容斥原理的核心就是减去不合法的。这个时候可能会多减,再把它加回来。 一个经典的应用是,你有若干个限制,彼此独立。你要求满足这些限制条件下的答案。 采用容斥原理是这样一个思路,先算出没有限制条件下的答案。再算出至少打破一个限制的答案。(就是我们强制要求一个限制满足,剩下的就不管他,因为我们是至少)。 把答案减去,我们又发现我们多减了那些同时打破两个限制的情况。在反过来加上至少打破两个限制的...

hanjinbo的博客 679

飞牛NAS1.1.19更新后SSH连不上?两步快速恢复连接

飞牛NAS1.1.19版本更新后SSH无法连接😟,实则是官方安全策略升级默认关闭了该服务,本文分享两步实操配置恢复SSH连接💻,还同步了官方的设备安全配置建议,帮助用户兼顾使用与设备防护🔒。

XiaoqiangClub的博客 2096

「学习笔记」容斥原理及其应用

错排问题 HDU 1465 #include &amp;amp;amp;amp;amp;lt;cstdio&amp;amp;amp;amp;amp;gt; long long dp[21]; int main() { dp[0] = dp[1] = 0; for(int i = 2; i &amp;amp;amp;amp;amp;lt;= 20; i ++) dp[i] = i * 1ll * dp[i - 1] + ((i &amp;amp;a

_Gion 746

uniapp - [全端兼容] 实现精美Editor富文本编辑器功能,uniApp全平台兼容的富文本插件组件用户可上传图片及对接服务器存储文件等,手机移动端H5网页富文本/小程序富文本/App富文本!

uni-app,h5移动端网页,微信小程序,支付宝小程序,Android安卓,苹果ios,app,nvue,uniapp富文本编辑器,uniapp中如何实现各平台都兼容的富文本编辑器,Editor富文本插件,uniApp微信小程序富文本,UNI-APP安卓苹果ios系统App端富文本组件,editor富文本编辑器如何实现上传图片,图片上传后不显示怎么办,如何配置图像上传功能,富文本图片上传怎么传到服务器中,获取图片路径,editor插入图片,富文本编辑器上传图片,报错怎么办,跨域CORS处理,配置不行无效

🏆 前端领域优质创作者 1万+

【STM32+K210项目】基于K210智能人脸识别+车牌识别系统(完整工程资料源码)

随着时代的进步和科技的迅猛发展,人们对居住安全的重视程度不断提升,对安全防范系统的需求也日益增强。在安防系统中,门禁系统占据着重要的位置。传统的门禁控制方式主要依靠钥匙、密码和门禁卡等,这些方式易于被破解和复制,安全性较低。然而,近年来,生物识别技术的迅速发展和成熟,为解决这一问题提供了新的方案。生物识别技术具备便携性、非易失性、不易遗忘以及难以盗用等优点,逐渐被引入到门禁系统中。传统的小区门禁系统往往依赖人工管理,存在一定的局限性,难以满足用户多样化的需求,也浪费了人力资源。

嵌入式技术开发 1万+

容斥原理(笔记)

对于三个圆, S1,S2,S3他们如上图所示,现在要求求他们所构成图形的面积,该如何去求? 这个问题很简单,S=S1+S2+S3−(S1∩S2)−(S1∩S3)−(S2∩S3)+(S1∩S2∩S3)S = S_1 + S_2 + S_3 - (S_1\cap S_2) - (S_1 \cap S_3) - (S_2 \cap S_3) + (S_1 \cap S_2 \cap S_3)S=S1​+S2​+S3​−(S1​∩S2​)−(S1​∩S3​)−(S2​∩S3​)+(S1​∩S2​∩S3​) 如果换.

qq_36102055的博客 1036

微信小程序 - request:fail errcode:10011 cronet_error_code:0 error_msg:network change, cancel all task请求报错

微信小程序请求接口,报request:fail errcode:10011是什么原因,uniapp微信小程序request:fail errcode:10011 cronet_error_code:0 error_msg:network change, cancel all task,微信小程序wx.request常规访问接口,有个别用户的接口请求频繁报错,UniApp 微信小程序uni.request请求接口报错:request:fail errcode:10011 的原因分析与解决方案,苹果ios,安卓

🏆 前端领域优质创作者 4566

容斥原理

容斥原理,容斥定理,容斥原理(详细)证明,排列组合,二进制,

Soul Singer的博客 4244

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

CSP初赛知识精讲--容斥原理

在计数时,必须注意没有重复,没有遗漏。为了使重叠部分不被重复计算,人们研究出一种新的计数方法,基本思想是:先不考虑重叠的情况,把包含于某内容中的所有对象的数目先计算出来,然后再把计数时重复计算的数目排斥除去,使得计算的结果既无遗漏又无重复,这种计数的方法称为容斥原理。某班有学生45人,每人在暑假里都参加体育训练队,其中参加足球队的有25人,参加排球队的有22人,参加游泳队的有24人,足球、排球都参加的有12人,足球、游泳都参加的有9人,排球、游泳都参加的有8人,问:三项都参加的有多少人?

没人说晚安的博客 1603

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

容斥原理训练 (16.04.10)

这又是一篇训练系列的博文,主题是容斥原理。 题目: UVA 10325 A - The Lottery poj 3904 Sky Code uvalive 7040 color hdu 4059 The Boss on Mars H - Visible TreesUVA 10325 A - The Lotteryhttps://uva.onlinejudge.org/index.php?

theArcticOcean 853

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

2019/3/28训练总结 容斥原理,矩阵快速幂

总结一下这周学习的知识点:容斥原理,矩阵快速幂,(高斯消元暂时没做题目所以不再今天总结了) 容斥原理: 用途:求解任意大小的集合,或者计算复合事件的概率 描述:要计算几个集合并集的大小,我们要先将所有单个集合的大小计算出来,然后减去所有两个集合相交的部分,再加回所有三个集合相交的部分,再减去所有四个集合相交的部分,依此类推,一直计算到所有集合相交的部分。 容斥原理的证明就不...

胖亚亚的小酒馆 328

【容斥原理】-训练总结

1. HDU - 2841 在n*m(n&lt;=1e5,m&lt;1e5)的矩阵中,每一个格子都有一棵树,小明站在(0,0),问他可以看到多少棵不被遮住的树?分析:当两棵树与小明在三点直线上,则小明只能看见一棵树,可以得出所有y/x==y0/x0这样的点(x,y)只能看见最简的(x,y),即x与y互质,那么小明看见不同树的个数就等于n,m中互质的数的对数。容斥原理可以求出一个集合内的数与一个数互...

tystrwor的博客 792

组合计数问题中容斥原理的应用

容斥原理作为数学中的一个重要定理,在ACM当中也有重要的应用,

wolf940509 848

组合数学:容斥原理及其应用

容斥原理 例题:{1,,2...n}的排列i1i2..in计数,其中1不在第一个位置 当k不在第一个位置的时候,第一个位置又n-1种可能,后面所有位置排列为(n-1)! 也可以用当k在第一个位置的时候 n! - (n-1)! = (n-1)!(n-1) 定理 集合S不具有性质P1,P2...PM的物体个数:

hhy518518的专栏 2536

容斥原理(组合数学)总结

本来一周左右应该可以完成的容斥,因为训练赛耽误了,最后2周才解决,现在总结下容斥原理 个人认为:容斥原理是属于一种模板题目,一般简单的都是之间打模板,稍难的题目运用到了数学分析和数论的其他知识。 容斥原理分为三种实现: 1.位运算与二进制枚举(容易理解) 2.队列数组(耗时最短) 3.递归(代码最短但不容易理解) http://blog.youkuaiyun.com/deepseazbw/arti

深海沧澜的博客 1739

训练周记及反思

由于最近个人感悟比较多,先写一下总结 这一周学的内容很少但是我觉得收获比较大,一开始的时候看了一点博弈论的内容,那个 grundy 函数有点抽象,剩下的内容都不算难理解,前几场 CF 打的不错,可能是最近的比赛打得太惨了。 中间被老师叫过去谈心,那天上午学也没有学进去,想了一下自己将来的规划,有重新组队的打算,但是其他队都不想折腾,队友比较难找,下次找场比赛和 lxh 试一下配合怎么样,我是实现打算把信奥上的大部分基础都过一遍,然后再挑最适合的专题给自己。最近的 CF 就忽然觉得可以出了,本来眼疼想去睡

C_Dreamy的博客 465

2019/4/7训练日记 容斥原理---莫比乌斯反演的本质

今天上午看了会莫比乌斯反演,后来开会,开会之后也没干啥事 中午吃完饭后一直开始看容斥原理 后来发现: 莫比乌斯反演的本质就是容斥(https://blog.youkuaiyun.com/ZLH_HHHH/article/details/78191689) 反演分为两种形式: ①约数型 对于等式 可以得到 ②倍数型 对于等式 ...

胖亚亚的小酒馆 1125

算法随笔 - 容斥原理学习

对于容斥原理的大部分题而言,枚举一定会超时的。但是可以用二进制进行优化。对于容斥原理的大部分题而言,n比较小,可以枚举。时发现处理重复集合用了容斥原理来做,感觉我对容斥原理不太熟悉,因此上网学了学容斥原理。个,在里面套个枚举长度的。,指数级别的时间复杂度。在补牛客多校7的I题。

田乐蒙的博客 350

牛客寒假多校训练赛第三场 G 大水题 容斥原理

/** 链接:https://www.nowcoder.com/acm/contest/75/G 题意:给出一个数n,求1到n中,有多少个数不是2 5 11 13的倍数; 容斥原理;可分为一类题的模板; */ #include&lt;bits/stdc++.h&gt; #define ll long long using namespace std; /*******************...

布呗之路 342
上一篇: 二分图博弈学习笔记
下一篇: 势函数和鞅的停时定理
sophilex
博客等级 码龄5年 840粉丝 155原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值