T1
//60分做法
我们发现对于这个式子它其实可以理解为对于每个(a mod i)都乘上(b mod i)的加和 与 (b
mod i)都乘上 (a mod i)的加和 的和,这样其实也就是求出sum(a mod i) * sum(b mod i)
但是题目要求 i = j时不能加,所以再做容斥原理即可。
时间复杂度 O(n)
//100分做法
//划重点
这题需要用到一个叫/*数论分块*/的东西,不做详细说明,证明和详解我觉得这个比较好
//https://www.cnblogs.com/luckyblock/p/12614236.html
于是的话呢对于suma 和 sumb也不做详解,CQOI2007余数求和就是搞这个的(自己luogu,那么我们的容斥原理
部分展开后就是
res = min(a,b) * a % mod * b % mod;
res = res - (b * (a / i) % mod * sum(i,j) % mod) - (a * (b / i) % mod * sum(i,j) % mod) + ((a / i) * (b / i) % mod * (SUM(j) - SUM(i - 1)) % mod);
//分割线
这题考场上真的懵了,数论题做得比较少,还需练习qwq
code:#include<cstdio>
#include<iostream>
#define ll long long
using namespace std;
const ll mod = 1e9 + 7;
ll inv2,inv6,a,b;
ll getr(ll x,ll n)
{
return n / (n / x);
}
ll getinv(ll x,ll y)
{
ll res = 1;
while(y > 0)
{
if(y % 2)res = res * x % mod;
y >>= 1;
x = x * x % mod;
}
return res;
}
ll sum(ll l,ll r)
{
return (l + r) * (r - l + 1) % mod * inv2 % mod;
}
ll SUM(ll n)
{
return (n + 1) * n % mod * (2 * n + 1) % mod * inv6 % mod;
}
int main()
{
inv2 = getinv(2,mod-2);
inv6 = getinv(6,mod-2);
scanf("%lld%lld",&a,&b);
ll res,suma,sumb;
res = suma = sumb = 0;
for(ll i = 1,j = 0;i <= a;i += 1)
{
j = getr(i,a);
suma += ((a * (j - i + 1) % mod - (a / i) * sum(i,j) % mod) % mod);
suma %= mod;
i = j;
}
if(suma < 0)suma += mod;
for(ll i = 1,j = 0;i <= b;i += 1)
{
j = getr(i,b);
sumb += ((b * (j - i + 1) % mod - (b / i) * sum(i,j) % mod) % mod);
sumb %= mod;
i = j;
}
if(sumb < 0)sumb += mod;
res = min(a,b) * a % mod * b % mod;
for(ll i = 1,j,p,q;i <= min(a,b);i += 1)
{
p = getr(i,a);
q = getr(i,b);
j = min(p,q);
res = res - (b * (a / i) % mod * sum(i,j) % mod) - (a * (b / i) % mod * sum(i,j) % mod) + ((a / i) * (b / i) % mod * (SUM(j) - SUM(i - 1)) % mod);
res = (res + mod) % mod;
i = j;
}
if(res < 0)res += mod;
printf("%lld\n",((((suma + mod) % mod * (sumb + mod) % mod + mod) % mod - res) + mod) % mod);
return 0;
}T2
首先化简题意,u的值:若分解质因数总个数为奇数就是-1否则1,若存在平方数是自己的因
数
那就是0。
对于这个东西我们不难用线性筛求出。
关键是怎么去模拟剩下w = w + u[w]的过程
我们发现每四个连续数一定有4是它们其中一个的因数,也就是说到这个点它就不动了!那我
们的最大周期就是4,那周期中有没有更小的循环周期呢?是有的!如果u_lastw = -1而现在
u_w = 1显然也是循环。
所以。。。。
懂了吧
//分割线
当时考场心态炸裂毕竟读不懂题。。。以后还是有自信的,要不然又 100-> 30了
code:
#include<cstdio>
#include<iostream>
#include<map>
using namespace std;
const int MAXN = 1e7 + 17;
int t,maxn,n[MAXN];long long k[MAXN];
int prime[MAXN],v[MAXN],u[MAXN],m,num[MAXN];
bool vis[MAXN];
int main()
{
cin >> t;
for(int i = 1;i <= t;i += 1)
scanf("%d%lld",&n[i],&k[i]);
for(int i = 2;i <= 1e7;i += 1)
{
if(v[i] == 0)
{
m++;
prime[m] = i;
u[i] = -1;
}
for(int j = 1;j <= m && prime[j] * i <= 1e7;j += 1)
{
v[prime[j] * i] = 1;
if(i % prime[j] == 0)
{
u[i * prime[j]] = 0;
break;
}
u[prime[j] * i] = -u[i];
}
}
u[1] = 1;
int tex = 0;
for(int i = 1;i <= t;i += 1)
{
tex = 0;
int w = n[i];
for(int j = 1;j <= k[i];j += 1)
{
int lastw = w;
w = w + u[w];
if(u[lastw] == -1 && u[w] == 1)
{
tex = 1;
if((k[i] - j) % 2)printf("%d\n",lastw);
else printf("%d\n",w);
break;
}
if(!u[w])
{
tex = 1;
printf("%d\n",w);break;
}
}
if(!tex)printf("%d\n",w);
}
return 0;
}T3
还没写无哇哇哇哇我好菜啊!!

京公网安备 11010502036488号