给个n,求1到n的所有数的约数个数的和~
第一行一个正整数n
输出一个整数,表示答案
3
5
样例解释: 1有1个约数1 2有2个约数1,2 3有2个约数1,3
n <= 100000000
#include
int deal(int n)
{
int ans=0;
for(int i=1;i<=n;i++)
ans+=n/i;
return ans;
}
int main()
{
int n;
//freopen("in.txt","r",stdin);
while(scanf("%d",&n)!=EOF)
printf("%d\n",deal(n));
return 0;
}
B
第一行两个数表示n,m
第二行n-1个数,第i个数表示第i个储物点与第i+1个储物点的距离ai
第三行n个数,表示每个储物点的东西个数bi
之后m行每行三个数x l r
对于每个询问输出一个数表示答案 答案对1000000007取模
5 5 2 3 4 5 1 2 3 4 5 1 1 5 3 1 5 2 3 3 3 3 3 1 5 5
125 72 9 0 70
对于100%的数据n,m <= 200000 , 0 <= ai,bi <= 2000000000
思路:
计算所有点到点1的距离以及前缀和,然后根据关系计算得到答案即可
另一种思路:计算前面所有点到 i 的权值和,但是不知道为什么一直错,找不到原因了
#include
#include
#include
using namespace std;
#define MAXN 200005
#define LL long long
#define mod 1000000007
int n,m;
LL a[MAXN],b[MAXN],s[MAXN];
void init(){
for(int i=2;i<=n;i++)
scanf("%lld",&a[i]),a[i]=(a[i]+a[i-1])%mod;
for(int i=1;i<=n;i++)
scanf("%lld",&b[i]),s[i]=(s[i-1]+a[i]*b[i])%mod,b[i]=(b[i]+b[i-1])%mod;
}
LL get_left(int l,int r,int x){
return a[x]*(b[r]-b[l-1])-(s[r]-s[l-1]);
}
LL get_right(int l,int r,int x){
return s[r]-s[l-1]-a[x]*(b[r]-b[l-1]);
}
int main()
{
//freopen("in.txt","r",stdin);
while(scanf("%d%d",&n,&m)!=EOF)
{
init();
while(m--)
{
int x,l,r;
scanf("%d%d%d",&x,&l,&r);
LL ans=0;
if(x>=r) ans=get_left(l,r,x);
else if(x<=l) ans=get_right(l,r,x);
else ans=get_left(l,x,x)+get_right(x,r,x);
printf("%lld\n",(ans%mod+mod)%mod);
}
}
return 0;
}
给你一个 n 个点,m 条边的无向图,求至少要在这个的基础上加多少条无向边使得任意两个点可达~
第一行两个正整数 n 和 m 。 接下来的m行中,每行两个正整数 i 、 j ,表示点i与点j之间有一条无向道路。
输出一个整数,表示答案
4 2 1 2 3 4
1
对于100%的数据,有n,m<=100000。
利用并查理求得连通块有ans个,则输出 ans-1即可
也可以利用dfs,bfs求得
#include
#include
#include
using namespace std;
#define MAXN 100005
int father[MAXN],visit[MAXN];
int find_it(int x){
int tempx=x,t;
while(tempx!=father[tempx])
tempx=father[tempx];
while(father[x]!=x){
t=father[x];
father[x]=tempx;
x=t;
}
return tempx;
}
void unite(int num1,int num2){
int tx=find_it(num1);
int ty=find_it(num2);
if(tx!=ty)
father[tx]=ty;
}
int main()
{
int n,m,a,b;
//freopen("in.txt","r",stdin);
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=0;i<=n;i++)
father[i]=i;
for(int i=0;i
给出一个集合和一个数m。
集合里面有n个质数。
请你求出从 1 到 m 的所有数中,至少能被集合中的一个数整除的数的个数。
第一行两个正整数 n 和 m 。 第二行n个正整数,分别为集合中的质数。
输出一个整数,表示符合要求的正整数的个数。
3 37 5 7 13
13
对于100%的数据,有n<=20,m为有符号64位正整数,集合内质数<=1000000000
容斥原理处理一下
注意这里n个数都是质数,我们可以直接两个数相乘得到最大公约数,如果不能保证是质数,则要求得最大公约数
因为18/6 + 18/9 - 18/lcm(6,9)答案才是正确的
#include
#include
#include
using namespace std;
#define LL long long
LL a[100];
LL n,m,ans;
LL gcd(LL a,LL b)
{
return b?gcd(b,a%b):a;
}
LL lcm(LL a,LL b)
{
return a*b/gcd(a,b);
}
void dfs(int now,LL num,int sym)
{
if(num) ans+=m/num*sym;
for(int i=now+1;i<=n;i++)
dfs(i,lcm(num,a[i]),-1*sym);
}
int main()
{
//freopen("in.txt","r",stdin);
while(scanf("%lld%lld",&n,&m)!=EOF)
{
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
ans=0;
for(int i=1;i<=n;i++)
dfs(i,a[i],1);
printf("%lld\n",ans);
}
return 0;
}