zoukankan      html  css  js  c++  java
  • test20180830

    所有试题限制均为128MB,1Sec
    总分100(•́へ•́╬)。

    试题一

    A题

    问题描述:

    Bob 有 n 个士兵,他们排成一列按照从左到右编号为 1 到 n,每个士兵都有自己的 IQ 值,Bob 喜欢有序的东西,他想要让这些士兵按照 IQ 的大小从小到大排序。于是 Bob 决定进行m 次操作,每次选一个士兵,让他开始整理部队。当士兵被选中的时候,士兵会向后的士兵(编号大于该士兵)发出指令。但是因为 IQ 的原因,只有 IQ 低于该士兵的士兵才会听从指令。那么这些士兵会按照 IQ 从小到大顺序重新排列在这些士兵之前的位置上,并重新编号。那么 Bob 想知道,当他选出一些士兵之后,总体士兵 IQ 的逆序对有多少个。

    输入:

    第一行包含三个整数 n,m,表示士兵的个数和 Bob 操作的次数。
    接下来 n 个数字,(a_1,a_2 dots a_n(a_i<10^9)),分别表示编号 1,2……n 的士兵的 IQ 值。

    输出:

    输出 m+1 的整数,分别是一开始的逆序对数,进行了 i 次操作后的逆序对数。

    样例输入:

    3 2
    2 3 1
    1
    1

    样例输出:

    2
    1
    1

    初始的逆序对数为 2,当选中第一个数的时候,后面小于 2 的数只有 1,重排和重编号后变
    为 1 3 2,逆序对数变成了 1。再次选中第一个数,后面没有小于 1 的数,所以都不会动,
    逆序对数不变。注(IQ 可能有相同的士兵)

    数据范围:

    对于 40%的数据,(1 leq n leq 20,1 leq m leq 20)
    对于 70%的数据,(1 leq n,m leq 10^3)
    对于 100%的数据,(1 leq n,m leq 10^5)

    分析

    没错,题意就是这样不清楚。输入格式还少了点东西。
    所谓的选出来重新排列的意思是提取出一些数,排序后放入原来提取他们的位置上。

    考场70分

    先离散化,然后直接模拟,用树状数组求逆序对。复杂度(O(N^2 log N))

    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<ctime>
    #include<iostream>
    #include<string>
    #include<vector>
    #include<list>
    #include<deque>
    #include<stack>
    #include<queue>
    #include<map>
    #include<set>
    #include<bitset>
    #include<algorithm>
    #include<complex>
    #pragma GCC optimize ("O0")
    using namespace std;
    template<class T> inline T read(T&x){
        T data=0;
    	int w=1;
        char ch=getchar();
        while(!isdigit(ch))
        {
    		if(ch=='-')
    			w=-1;
    		ch=getchar();
    	}
        while(isdigit(ch))
            data=10*data+ch-'0',ch=getchar();
        return x=data*w;
    }
    typedef long long ll;
    const int INF=0x7fffffff;
    
    const int MAXN=1e5+7;
    int n,a[MAXN],date[MAXN];
    int b[MAXN],cnt,pos[MAXN];
    int c[MAXN];
    
    inline int lowbit(int x)
    {
    	return x&-x;
    }
    
    inline void add(int p,int v)
    {
    	while(p<=n)
    	{
    		c[p]+=v;
    		p+=lowbit(p);
    	}
    }
    
    inline int query(int p)
    {
    	int res=0;
    	while(p)
    	{
    		res+=c[p];
    		p-=lowbit(p);
    	}
    	return res;
    }
    
    inline int solve()
    {
    	int ans=0;
    	for(int i=1;i<=n;++i)
    	{
    		ans+=query(n)-query(a[i]);
    		add(a[i],1);
    	}
    	memset(c,0,sizeof(int)*(n+7));
    	return ans;
    }
    
    int main()
    {
      freopen("A.in","r",stdin);
      freopen("A.out","w",stdout);
    	int m;
    	read(n);read(m);
    	for(int i=1;i<=n;++i)
    		date[i]=read(a[i]);
    	sort(date+1,date+n+1); // discretization
    	for(int i=1;i<=n;++i)
    		a[i]=lower_bound(date+1,date+n+1,a[i])-date;
    /*	for(int i=1;i<=n;++i)
    		cerr<<a[i]<<" ";
    	cerr<<endl;*/
    	printf("%d
    ",solve());
    	while(m--)
    	{
    		int x;
    		read(x);
    		pos[cnt=1]=x;
    		b[cnt]=a[x];
    		for(int i=x;i<=n;++i)
    			if(a[i]<a[x])
    			{
    				pos[++cnt]=i;
    				b[cnt]=a[i];
    			}
    		sort(b+1,b+cnt+1);
    		for(int i=1;i<=cnt;++i)
    			a[pos[i]]=b[i];
    		printf("%d
    ",solve());
    	}
    //  fclose(stdin);
    //  fclose(stdout);
        return 0;
    }
    

    标解

    我们考虑计算一个数之后有多少比他小的数来计算整体的逆序对数。可以发现的是,当我们对一个数字进行操作是,所有比他的数对逆序对的贡献是不变,比他小且在他后面的逆序对数的贡献要变成 0。所以对于一个数来说,他的贡献变为 0 的时刻就是在他前面比他大的而且最早进行的操作对应的时刻。这样的话我们就可以用线段树来维护了,当然也可以分治来做,复杂度 (O(N log N))

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #include <ctime>
    #include <iostream>
    #include <algorithm>
    #include <set>
    #include <map>
    #include <vector>
    #include <string>
    #include <queue>
    using namespace std;
    typedef long long LL;
    #define For(i,a,b) for (int i = (a); i <= (b); i++)
    #define Cor(i,a,b) for (int i = (a); i >= (b); i--)
    #define rep(i,a) for (int i = 0; i < a; i++)
    #define Fill(a,b) memset(a,b,sizeof(a))
    const int maxn = 500010;
    const int maxm = 1e6 + 10;
    const int inf = 1e9;
    struct node
    {
    	int v, id, p;
    }P[maxn];
    int n, m;
    int f[maxn];
    void init()
    {
    	scanf("%d%d", &n, &m);
    	For(i, 1, n)
    		scanf("%d", &P[i].v), P[i].id = i, P[i].p = f[i] = inf;
    	rep(i, m)
    	{
    		int x;
    		scanf("%d", &x);
    		if (P[x].p == inf)
    			P[x].p = f[x] = i;
    	}
    }
    struct BIT
    {
    	int val[maxm];
    	void add(int x, int v)
    	{
    		for (int i = x; i < maxm; i += i & (-i))
    			val[i] += v;
    	}
    	int ask(int x)
    	{
    		int ret = 0;
    		for (int i = x; i; i -= i & (-i))
    			ret += val[i];
    		return ret;
    	}
    }b;
    int g[maxn];
    LL F[maxn];
    int mn[maxn<<2];
    void up(int id,int l,int r,int v,int w)
    {
        if(l==r){
            mn[id]=min(mn[id],w);return;
        }
        int mid=(l+r)>>1;
        if(v<=mid) up(id<<1,l,mid,v,w);
        else up(id<<1|1,mid+1,r,v,w);
        mn[id]=min(mn[id<<1],mn[id<<1|1]);
    }
    int q(int id,int l,int r,int tl,int tr)
    {
        if(tl==l&&r==tr) return mn[id];
        int mid=(l+r)>>1;
        if(tr<=mid) return q(id<<1,l,mid,tl,tr);
        else if(tl>mid) return q(id<<1|1,mid+1,r,tl,tr);
        else return min(q(id<<1,l,mid,tl,mid),q(id<<1|1,mid+1,r,mid+1,tr));
    }
    int a[maxn];
    map<int,int> mp;
    void solve()
    {
    	LL ans = 0;
    	Cor(i, n, 1)
    	{
    		g[i] = b.ask(P[i].v);
    		b.add(P[i].v + 1, 1);
    		ans += g[i];
    		a[i]=P[i].v;
    	}
    	sort(a+1,a+1+n);
    	int cnt=1;
    	for(int i=1;i<=n;i++)
        {
            if(mp[a[i]]) continue;
            mp[a[i]]=cnt++;
        }
    	printf("%lld
    ", ans);
    	memset(mn,127,sizeof(mn));
    	for(int i=1;i<=n;i++)
        {
            P[i].v=mp[P[i].v];
            up(1,1,cnt,P[i].v,P[i].p);
            int t=q(1,1,cnt,P[i].v,cnt);
            if(t>m) continue;
            F[t]+=g[i];
        }
    	rep(i, m)
    	{
    		ans -= F[i];
    		printf("%lld
    ", ans);
    	}
    }
    int main()
    {
    	freopen("A.in","r",stdin);
    	freopen("A.out","w",stdout);
    	init();
    	solve();
    	return 0;
    }
    

    然而实际上这份代码是错的,他对相等的IQ的处理方式不正确。同学有不用线段树的期望(O(log N))的做法。

    试题二

    B题

    问题描述:

    四个机器人,在 3 * 3 的方格里,一开始四个机器人分别站在 9 个格子上,每一步机器人可
    以往临近的一个格子移动或留在原地(同一个格子可以有多个机器人停留),经过 n 步后有
    多少种不同的走法,使得每个毯子上都有 1 机器人停留。由于方法数量巨大,输出 Mod
    (10^9 + 7) 的结果。

    输入:

    第一行包含一个整数 n。

    输出:

    输出一行输出走法的数量 Mod (10^9 + 7)

    样例输入:

    1

    样例输出:

    229

    数据范围:

    对于 40%的数据,(1 leq nleq 10)
    对于 70%的数据,(1 leq n leq 10^6)
    对于 100%的数据,(1 leq n leq 10^{18})

    分析

    四个机器人在九个格子上?不明所以。

    考场爆零做法

    打表过样例,随机出奇迹!

    标解

    实际上按AC了的同学的理解,每个格子上都有一个机器人。
    一共只有 9 个格子,我们对它进行编号,可以构成一个 9×9 的转移矩阵,进行快速幂之后 9!的枚举每个棋子最终的位置即可。复杂度 (O(9^3×log k+9!))
    矩阵元素(a_{i,j})存的是(i)是否能一步到(j(i eq j))(1(i=j))。后面为1是因为可以选择不走。

    #include <bits/stdc++.h>
    using namespace std;
    const int mod=1e9+7;
    
    struct Matrix
    {
        long long a[9][9];
    }ma;
    Matrix mull(Matrix a,Matrix b)
    {
        Matrix ans;
        for(int i=0;i<9;i++)
        {
            for(int j=0;j<9;j++)
            {
                ans.a[i][j]=0;
                for(int k=0;k<9;k++)
                    ans.a[i][j]=(ans.a[i][j]+a.a[i][k]*b.a[k][j])%mod;
            }
        }
        return ans;
    }
    Matrix fast(long long ci,Matrix num)
    {
        Matrix ans;
        for(int i=0;i<9;i++)
            for(int j=0;j<9;j++)
            ans.a[i][j]=(i==j);
        while(ci){
            if(ci&1) ans=mull(ans,num);
            num=mull(num,num);ci=ci>>1;
        }
        return ans;
    }
    int a[10];
    int main()
    {
    	freopen("B.in","r",stdin);
    	freopen("B.out","w",stdout);
        for(int i=0;i<9;i++)
            for(int j=0;j<9;j++)
                ma.a[i][j]=((abs(i%3-j%3)+abs(i/3-j/3))==1);
        for(int i=0;i<9;i++)
            ma.a[i][i]=1;
        long long n;
        scanf("%lld",&n);
        ma=fast(n,ma);
        for(int i=0;i<9;i++)
            a[i]=i;
        long long ans=0;
        for(int i=0;i<362880;i++)
        {
            long long tmp=1;
            for(int j=0;j<9;j++)
            {
                tmp=tmp*ma.a[j][a[j]]%mod;
            }
            ans=(ans+tmp)%mod;
            next_permutation(a,a+9);
        }
        printf("%lld
    ",ans);
        return 0;
    }
    

    试题三

    C题

    问题描述:

    计算 gcd(i,j)的 k 次方的和,其中 (1 leq i leq n,1 leq j leq n);

    输入:

    第一行包含两个整数 n,k。

    输出:

    输出一行,表示对应的答案。

    样例输入:

    2 2

    样例输出:

    7

    数据范围:

    对于 40%的数据,(1 leq n leq 10^3)
    对于 70%的数据,(1 leq n leq 10^6)
    对于 100%的数据,(1 leq n leq 10^{10})
    对于所有的数据 (1 leq k leq 5)

    分析

    考场30分(30分?)

    [sum_{t=1}^nsum_{i=1}^nsum_{j=1}^n[gcd(i,j)=k]cdot t^k\ =sum_{t=1}^nt^ksum_{i=1}^{lfloor n/t floor}sum_{j=1}^{lfloor n/t floor}[gcd(i,j)=1]\ =sum_{t=1}^{n}t^ksum_{i=1}^{lfloor n/t floor}sum_{j=1}^{lfloor n/t floor}sum_{d|iwedge d|j}mu(d)\ =sum_{t=1}^nt^ksum_{d=1}^{lfloor n/t floor}lfloorfrac{n}{dt} floor^2mu(d)\ =sum_{x=1}^{n}lfloorfrac{n}{x} floor^2sum_{d|x}mu(d)(frac{x}{d})^k ]

    (f(x)=x^k),则原式

    [=sum_{x=1}^{n}lfloorfrac{n}{x} floor^2(mu*f)(x) ]

    (O(N))预处理(mu,f),然后可以(O(N ln N))预处理它们的狄利克雷卷积,最后(O(sqrt{n}))查询。

    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<ctime>
    #include<iostream>
    #include<string>
    #include<vector>
    #include<list>
    #include<deque>
    #include<stack>
    #include<queue>
    #include<map>
    #include<set>
    #include<bitset>
    #include<algorithm>
    #include<complex>
    #pragma GCC optimize ("O0")
    using namespace std;
    template<class T> inline T read(T&x){
        T data=0;
    	int w=1;
        char ch=getchar();
        while(!isdigit(ch))
        {
    		if(ch=='-')
    			w=-1;
    		ch=getchar();
    	}
        while(isdigit(ch))
            data=10*data+ch-'0',ch=getchar();
        return x=data*w;
    }
    typedef long long ll;
    const int INF=0x7fffffff;
    
    void write(__int128 x)
    {
    	stack<int>S;
    	while(x)
    	{
    		S.push(x%10);
    		x/=10;
    	}
    	while(!S.empty())
    	{
    		putchar('0'+S.top());
    		S.pop();
    	}
    }
    
    const int MAXN=1e6+7;
    int n,k;
    
    int prime[MAXN],pcnt;
    int mu[MAXN];
    
    void getmu()
    {
    	mu[1]=1,prime[1]=1;
    	for(int i=2;i<=n;++i)
    	{
    		if(!prime[i])
    		{
    			prime[++pcnt]=i;
    			mu[i]=-1;
    		}
    		for(int j=1;j<=pcnt&&i*prime[j]<=n;++j)
    		{
    			prime[i*prime[j]]=1;
    			if(i%prime[j]==0)
    			{
    				mu[i*prime[j]]=0;
    				break;
    			}
    			mu[i*prime[j]]=-mu[i];
    		}
    	}
    }
    
    __int128 f[MAXN];
    
    __int128 qpow(__int128 x,int k)
    {
    	__int128 ans=1;
    	while(k)
    	{
    		if(k&1)
    			ans*=x;
    		x*=x,k>>=1;
    	}
    	return ans;
    }
    
    void getf()
    {
    	for(int i=1;i<=n;++i)
    		f[i]=qpow(i,k);
    }
    
    __int128 g[MAXN];
    
    void getg()
    {
    	for(int i=1;i<=n;++i)
    		for(int j=1;j*i<=n;++j)
    			g[i*j]+=mu[i]*f[j];
    	for(int i=1;i<=n;++i)
    		g[i]+=g[i-1];
    }
    
    __int128 solve()
    {
    	__int128 ans=0;
    	int j;
    	for(int i=1;i<=n;i=j+1)
    	{
    		j=n/(n/i);
    		ans+=(__int128)(n/i)*(n/i)*(g[j]-g[i-1]);
    /*		cerr<<i<<" ";
    		write(ans);
    		cerr<<endl;*/
    	}
    	return ans;
    }
    
    int main()
    {
      freopen("C.in","r",stdin);
      freopen("C.out","w",stdout);
    	read(n);read(k);
    	getmu();
    /*	cerr<<"mu:"<<endl;
    	for(int i=1;i<=n;++i)
    		cerr<<i<<" mu="<<mu[i]<<endl;*/
    	getf();
    /*	cerr<<"f:"<<endl;
    	for(int i=1;i<=n;++i)
    	{
    		cerr<<i<<" f=";
    		write(f[i]);
    		cerr<<endl;
    	}*/
    	getg();
    /*	cerr<<"g:"<<endl;
    	for(int i=1;i<=n;++i)
    	{
    		cerr<<i<<" g=";
    		write(g[i]-g[i-1]);
    		cerr<<endl;
    	}*/
    	write(solve());
    //  fclose(stdin);
    //  fclose(stdout);
        return 0;
    }
    

    然而为什么30分呢?不应该70分吗?
    因为题目少说了一句“对(10^9+7)取模”。
    所以下面的程序是70分的。

    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<ctime>
    #include<iostream>
    #include<string>
    #include<vector>
    #include<list>
    #include<deque>
    #include<stack>
    #include<queue>
    #include<map>
    #include<set>
    #include<bitset>
    #include<algorithm>
    #include<complex>
    #pragma GCC optimize ("O0")
    using namespace std;
    template<class T> inline T read(T&x){
        T data=0;
    	int w=1;
        char ch=getchar();
        while(!isdigit(ch))
        {
    		if(ch=='-')
    			w=-1;
    		ch=getchar();
    	}
        while(isdigit(ch))
            data=10*data+ch-'0',ch=getchar();
        return x=data*w;
    }
    typedef long long ll;
    const int INF=0x7fffffff;
    
    void write(__int128 x)
    {
    	stack<int>S;
    	while(x)
    	{
    		S.push(x%10);
    		x/=10;
    	}
    	while(!S.empty())
    	{
    		putchar('0'+S.top());
    		S.pop();
    	}
    }
    
    const int MAXN=1e6+7;
    int n,k;
    
    int prime[MAXN],pcnt;
    int mu[MAXN];
    
    void getmu()
    {
    	mu[1]=1,prime[1]=1;
    	for(int i=2;i<=n;++i)
    	{
    		if(!prime[i])
    		{
    			prime[++pcnt]=i;
    			mu[i]=-1;
    		}
    		for(int j=1;j<=pcnt&&i*prime[j]<=n;++j)
    		{
    			prime[i*prime[j]]=1;
    			if(i%prime[j]==0)
    			{
    				mu[i*prime[j]]=0;
    				break;
    			}
    			mu[i*prime[j]]=-mu[i];
    		}
    	}
    }
    
    __int128 f[MAXN];
    
    __int128 qpow(__int128 x,int k)
    {
    	__int128 ans=1;
    	while(k)
    	{
    		if(k&1)
    			ans*=x;
    		x*=x,k>>=1;
    	}
    	return ans;
    }
    
    void getf()
    {
    	for(int i=1;i<=n;++i)
    		f[i]=qpow(i,k);
    }
    
    __int128 g[MAXN];
    
    void getg()
    {
    	for(int i=1;i<=n;++i)
    		for(int j=1;j*i<=n;++j)
    			g[i*j]+=mu[i]*f[j];
    	for(int i=1;i<=n;++i)
    		g[i]+=g[i-1];
    }
    
    __int128 solve()
    {
    	__int128 ans=0;
    	int j;
    	for(int i=1;i<=n;i=j+1)
    	{
    		j=n/(n/i);
    		ans+=(__int128)(n/i)*(n/i)*(g[j]-g[i-1]);
    /*		cerr<<i<<" ";
    		write(ans);
    		cerr<<endl;*/
    	}
    	return ans;
    }
    
    int main()
    {
      freopen("C.in","r",stdin);
      freopen("C.out","w",stdout);
    	read(n);read(k);
    	getmu();
    /*	cerr<<"mu:"<<endl;
    	for(int i=1;i<=n;++i)
    		cerr<<i<<" mu="<<mu[i]<<endl;*/
    	getf();
    /*	cerr<<"f:"<<endl;
    	for(int i=1;i<=n;++i)
    	{
    		cerr<<i<<" f=";
    		write(f[i]);
    		cerr<<endl;
    	}*/
    	getg();
    /*	cerr<<"g:"<<endl;
    	for(int i=1;i<=n;++i)
    	{
    		cerr<<i<<" g=";
    		write(g[i]-g[i-1]);
    		cerr<<endl;
    	}*/
    	write(solve()%int(1e9+7));
    //  fclose(stdin);
    //  fclose(stdout);
        return 0;
    }
    

    WTF?

    标解

    题解里给的公式有很大的问题,不好复制,我直接放上我的分析。
    先定义一个辅助函数(f)

    [f(n)=sum_{i=1}^ngcd(i,n)^k\ =sum_{d|n}sum_{i=1}^nd^k[gcd(i,n)=d]\ =sum_{d|n}d^ksum_{i=1}^n[gcd(frac{i}{d},frac{n}{d})=1]\ =sum_{d|n}d^kvarphi(frac{n}{d})\ =sum_{d|n}(frac{n}{d})^kvarphi(d) ]

    再用(f)表达出结果

    [sum_{i=1}^nsum_{j=1}^ngcd(i,j)^k\ =2 cdot sum_{i=1}^nf(i)-sum_{i=1}^ni^k ]

    最后推一下(f)的前缀和

    [sum_{i=1}^nf(i)\ =sum_{i=1}^nsum_{d|i}(frac{i}{d})^kvarphi(d)\ =sum_{t=1}^nt^ksum_{d=1}^{lfloor n/t floor}varphi(d)\ =sum_{t=1}^nt^kF(lfloorfrac{n}{t} floor) ]

    可用求欧拉函数前缀和的方式求解该式,复杂度(O(n^{frac{3}{4}}))

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=5000005;
    const int mod=1e9+7;
    int pri[maxn],fi[maxn],t;
    bool flag[maxn];
    long long sumfi[maxn];
    long long mod2,mod3,mod6,mod12,mod30;
    long long fast(long long num,int ci)
    {
        long long ans=1;
        while(ci)
        {
            if(ci&1) ans=ans*num%mod;
            num=num*num%mod;ci=ci>>1;
        }
        return ans;
    }
    map<long long ,long long>mp;
    void pre()
    {
        t=0;memset(flag,0,sizeof(flag));
        fi[1]=1;
        for(int i=2;i<maxn;i++)
        {
            if(!flag[i]){
                pri[t++]=i;fi[i]=i-1;
            }
            for(int j=0;j<t&&pri[j]*i<maxn;j++)
            {
                flag[pri[j]*i]=1;
                if(i%pri[j]==0){
                    fi[i*pri[j]]=fi[i]*pri[j];
                    break;
                }
                fi[i*pri[j]]=fi[i]*(pri[j]-1);
            }
        }
        for(int i=1;i<maxn;i++)
        {
            sumfi[i]=sumfi[i-1]+fi[i];
            if(sumfi[i]>=mod) sumfi[i]-=mod;
        }
        mod2=fast(2,mod-2);
        mod3=fast(3,mod-2);
        mod6=fast(6,mod-2);
        mod12=fast(12,mod-2);
        mod30=fast(30,mod-2);
        mp.clear();
    }
    
    long long gett(long long n,int k)
    {
        n%=mod;
        if(k==1)
            return n*(n+1)/2%mod;
        if(k==2)
            return n*(n+1)%mod*(2*n+1)%mod*mod6%mod;
        if(k==3){
            long long t=n*(n+1)/2%mod;;
            return t*t%mod;
        }
        if(k==4){
            return n*(n+1)%mod*(2*n+1)%mod*((3*n*n%mod+3*n-1)%mod)%mod*mod30%mod;
        }
        if(k==5){
            long long t=n*(n+1)%mod;
            t=t*t%mod;
            t=t*((2*n*n%mod+2*n-1)%mod)%mod;
            t=t*mod12%mod;
            return t;
        }
    }
    long long solve(long long u)
    {
        if(u<maxn){
            return sumfi[u];
        }
        if(mp[u]) return mp[u];
        long long tmp=u%mod;
        long long ans=tmp*(tmp+1)/2%mod;
        for(long long i=2,j;i<=u;i=j+1)
        {
            j=u/(u/i);
            ans=(ans-solve(u/i)*(j-i+1))%mod;
        }
        ans%=mod;
        if(ans<0) ans+=mod;
        mp[u]=ans;
        return ans;
    }
    
    int main()
    {
    	freopen("C.in","r",stdin);
    	freopen("C.out","w",stdout);
        pre();
        long long n;
        int k;
        scanf("%lld%d",&n,&k);
        long long ans=0;
        for(long long i=1,j;i<=n;i=j+1)
        {
            j=n/(n/i);
            ans=(ans+solve(n/i)*(gett(j,k)-gett(i-1,k)))%mod;
        }
        ans=ans*2;
        ans=ans-gett(n,k);
        ans%=mod;
        if(ans<0) ans+=mod;
        printf("%lld
    ",ans);
        return 0;
    }
    

    但是杜教筛可以做到(O(n^{frac{2}{3}})),并且标程也是(O(n^{frac{2}{3}}))的。

  • 相关阅读:
    java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized...
    Spring Security 自定义 登陆 权限验证
    springboot中使用spring security,登录url就出现403错误
    RocketMQ最佳实践
    JS 中获取服务器时间的注意点
    许小年:中国经济刚入寒冬,四万亿也救不了
    RestTemplate发送GET请求
    String类的format方法的用法
    参数的打包和解包实例
    16.return 返回值
  • 原文地址:https://www.cnblogs.com/autoint/p/9560622.html
Copyright © 2011-2022 走看看