牛客練習賽8

約數個數的和

時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 32768K,其他語言65536K
64bit IO Format: %lld

題目描述

給個n,求1到n的所有數的約數個數的和~

輸入描述:

第一行一個正整數n

輸出描述:

輸出一個整數,表示答案
示例1

輸入

3

輸出

5

說明

樣例解釋:
1有1個約數1
2有2個約數1,2
3有2個約數1,3

備註:

n <= 100000000
#include<iostream>
using namespace std;
int main()
{
    long long n,ans=0;
    cin>>n;
    for(long long i=1;i<=n/2;i++)
    {
        ans+=n/i;
    }
    ans+=n-n/2;
    cout<<ans<<endl;
    return 0;
}

儲物點的距離

時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 131072K,其他語言262144K
64bit IO Format: %lld

題目描述


 一個數軸,每一個儲物點會有一些東西,同時它們之間存在距離。
每次給個區間[l,r],查詢把這個區間內所有儲物點的東西運到另外一個儲物點的代價是多少?
比如儲物點i有x個東西,要運到儲物點j,代價爲x * dist( i , j )
dist就是儲物點間的距離。 


輸入描述:

第一行兩個數表示n,m

第二行n-1個數,第i個數表示第i個儲物點與第i+1個儲物點的距離ai

第三行n個數,表示每個儲物點的東西個數bi

之後m行每行三個數x l r

表示查詢要把區間[l,r]儲物點的物品全部運到儲物點x的花費
每次查詢獨立

輸出描述:

對於每個詢問輸出一個數表示答案
答案對1000000007取模
示例1

輸入

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

#include<bits/stdc++.h>
using namespace std;
#define N 200010
#define mo 1000000007
int a[N];
long long dis[N],sum[N],cnt[N];
int main(){
    int n,m,i;
    scanf("%d%d",&n,&m);
    for (i=2;i<=n;i++) scanf("%d",&a[i]);
    for (i=1;i<=n;i++) dis[i]=(dis[i-1]+a[i])%mo;
    for (i=1;i<=n;i++){
        int x;
        scanf("%d",&x);
        cnt[i]=(cnt[i-1]+x)%mo;
        sum[i]=(sum[i-1]+x*dis[i])%mo;
    }
    for (i=1;i<=m;i++){
        long long ans=0;
        int x,l,r;
        scanf("%d%d%d",&x,&l,&r);
        if (l>x) ans=sum[r]-sum[l-1]-dis[x]*(cnt[r]-cnt[l-1])%mo;
        else if (r<x) ans=dis[x]*(cnt[r]-cnt[l-1])%mo-(sum[r]-sum[l-1]);
        else ans=sum[r]-sum[x]-dis[x]*(cnt[r]-cnt[x])%mo+dis[x]*(cnt[x-1]-cnt[l-1])%mo-(sum[x-1]-sum[l-1]);
        printf("%lld\n",(ans%mo+mo)%mo);
    }
    return 0;
}

加邊的無向圖

時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 32768K,其他語言65536K
64bit IO Format: %lld

題目描述

給你一個 n 個點,m 條邊的無向圖,求至少要在這個的基礎上加多少條無向邊使得任意兩個點可達~ 

輸入描述:

第一行兩個正整數 n 和 m 。
接下來的m行中,每行兩個正整數 i 、 j ,表示點i與點j之間有一條無向道路。

輸出描述:

輸出一個整數,表示答案
示例1

輸入

4 2
1 2
3 4

輸出

1

備註:

對於100%的數據,有n,m<=100000。
#include<iostream>
#include<cstdio>
using namespace std;
long n,m,ans,f[100050];
long find(long x)
{
     return f[x]==x?x:f[x]=find(f[x]);
}
int main()
{
    scanf("%ld%ld",&n,&m);
    for(long i=1;i<=n;i++)
    {
        f[i]=i;
    }
    for(long i=1;i<=m;i++)
    {
        long x,y;
        scanf("%ld%ld",&x,&y);
        f[find(x)]=find(y);
    }
    for(long i=1;i<=n;i++)
    {
        if(f[i]==i)
            ans++;
    }
    cout<<ans-1<<endl;
    return 0;
}

集合中的質數

時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 32768K,其他語言65536K
64bit IO Format: %lld

題目描述

給出一個集合和一個數m。

集合裏面有n個質數。

請你求出從 1 到 m 的所有數中,至少能被集合中的一個數整除的數的個數。

輸入描述:

第一行兩個正整數 n 和 m 。
第二行n個正整數,分別爲集合中的質數。

輸出描述:

輸出一個整數,表示符合要求的正整數的個數。
示例1

輸入

3 37
5 7 13

輸出

13

備註:

對於100%的數據,有n<=20,m爲有符號64位正整數,集合內質數<=1000000000
沒做出來,別人的代碼==
#include "stdio.h"
int main(){
    int n ;
    long long int m ;
    scanf("%d %lld" , &n ,&m );
    int value[n] ;
    for(int i = 0; i < n ; i ++)
    {
        scanf("%d" , &value[i]) ;
    }
    long long result = 0 ;
    for(int i = 0 ; i < (1<< n) ; i ++)
    {
        int count = 0 ;
        long long sum = 1 ;
        for(int j = 0 ; j < n ;  j ++) {
            if(i & (1<<j))
            {
                sum*= value[j] ;
                count ++ ;
            }
        }
        if( count & 1 )
            result += m/sum ;
        else if( count )
            result -= m/sum ;
    }
    printf("%lld" , result) ;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章