1.求
的值:
我们要求这些绿色点的和,我们发现,在一定的区间内他们的值是相同的,所以我们只需要知道他们的区间长度就行。
我们发现,假设我们知道
,我们要求出来j,怎么求呢?
利用小学知识容易知道,所以块的区间长度是
所以
void solve(int n,int m)
{
int ans=0;
for(int i=1,j;i<=n;i=j+1)
{
j=min(n/(n/i),m/(m/i));
ans+=(m/i)*(n/i)*(j-i+1);
}
cout<<ans<<"\n";
}
2.求
的值:
我们可以找他们块区间的公共部分
void solve(int n,int m)
{
int ans=0;
for(int i=1,j;i<=n;i=j+1)
{
j=min(n/(n/i),m/(m/i));
ans+=(m/i)*(n/i)*(j-i+1);
}
cout<<ans<<"\n";
}
3.求
的值:
,因为在一定的区间内,
是相等的,所以我们只需要求
的和就行了。
void solve(int n)
{
int ans=0;
for(int i=1,j;i<=n;i=j+1)
{
j=n/(n/i);
ans+=(i+j)*(n/i)*(j-i+1)/2;
}
cout<<ans<<"\n";
}
以上三题的公式我们都可以写成这种形式
4.求
的值:(其中
)
这一道题是上面三道的结合,结合上面题目的思路,我们先预处理出来 的前缀和,再
循环求出
,然后在
个
中求出
的最小值为
, 然后求出
的值为
,最后讲
加上
。(最后的答案可能是负数,所以我们要
)
/*
by:lwq132lwq
*/
#include<bits/stdc++.h>
using namespace std;
#define IO ios::sync_with_stdio(false);cin.tie(0);
#define int long long
#define dd double
#define re register
#define il inline
#define pb push_back
#define fr frist
#define sc second
template <class T> void read(T &x){
x=0;int f=0;char ch=getchar();
while(ch<'0'||ch>'9'){f|=(ch=='-');ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
x=f?-x:x;return ;
}
bool cmp(int x,int y){return x>y;}
dd ddabs(double x){if(x<0) return -x;else return x;}
int gcd(int a, int b){return b ? gcd(b,a%b):a;}
int max(int a,int b){if(a>b) return a;else return b;}
int min(int a,int b){if(a<b) return a;else return b;}
const int maxn=1e6+10;
const int mod=1e9+7;
int N[maxn],f[maxn],s[maxn];
void solve(int m)
{
int ans=0,mi=0x3f3f3f3f;
for(int i=1;i<=m;i++) read(N[i]),mi=min(mi,N[i]);
for(int i=1,j;i<=mi;i=j+1)
{
j=N[1]/(N[1]/i);
int Q=1;
for(int t=1;t<=m;t++)
j=min(j,N[t]/(N[t]/i));
for(int t=1;t<=m;t++)
Q=Q*(N[t]/i)%mod;
ans=(Q*(s[j]-s[i-1])%mod+ans)%mod;
}
cout<<(ans+mod)%mod<<"\n";
}
signed main()
{
f[1]=1;f[0]=1;s[0]=1;
for(int i=2;i<=maxn;i++)
{
f[i]=(f[i-1]+f[i-2])%mod;
}
for(int i=1;i<=maxn;i++)
s[i]=(s[i-1]+f[i])%mod;
int m;
while(scanf("%lld",&m)!=EOF) solve(m);
return 0;
}
/**********************************************************************
Problem: 1436
User: lwq132lwq
Language: C++
Result: AC
Time:846 ms
Memory:25616 kb
**********************************************************************/
5.求
的值:[CQOI2007]余数求和 - 洛谷
简单变形一下得到 。我们通过这些变成了第二题的形式,然后要分情况讨论
和
的情况。
/*
by:lwq132lwq
*/
#include<bits/stdc++.h>
using namespace std;
#define IO ios::sync_with_stdio(false);cin.tie(0);
#define int long long
#define dd double
#define re register
#define il inline
#define pb push_back
#define fr frist
#define sc second
template <class T> void read(T &x){
x=0;int f=0;char ch=getchar();
while(ch<'0'||ch>'9'){f|=(ch=='-');ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
x=f?-x:x;return ;
}
bool cmp(int x,int y){return x>y;}
dd ddabs(double x){if(x<0) return -x;else return x;}
int gcd(int a, int b){return b ? gcd(b,a%b):a;}
int max(int a,int b){if(a>b) return a;else return b;}
int min(int a,int b){if(a<b) return a;else return b;}
//const int maxn=
void solve(int n,int k)
{
int ans=n*k;
for(int i=1,j;i<=n;i=j+1)
{
if(k/i!=0) j=min((k/(k/i)),n);
else j=n;
ans-=(j+i)*(k/i)*(j-i+1)/2;
}
printf("%lld\n",ans);
}
signed main()
{
int n,k;
while(scanf("%lld %lld",&n,&k)!=EOF) solve(n,k);
return 0;
}
/**********************************************************************
Problem: 1437
User: lwq132lwq
Language: C++
Result: AC
Time:127 ms
Memory:2176 kb
**********************************************************************/
结语:
对今天集训学的内容的总结,部分图片来自CSGrandeur教练的ppt