码迷,mamicode.com
首页 > 其他好文 > 详细

洛谷数论{水题}集合

时间:2016-08-13 14:08:01      阅读:775      评论:0      收藏:0      [点我收藏+]

标签:

1. P1327数列排序

题目描述

给定一个数列{an},这个数列满足ai≠aj(i≠j),现在要求你把这个数列从小到大排序,每次允许你交换其中任意一对数,请问最少需要几次交换?

输入输出格式

输入格式:

第一行,正整数n (n<=100,000)。

以下若干行,一共n个数,用空格分隔开,表示数列{an},任意-231<ai<231。

输出格式:

只有一行,包含一个数,表示最少的交换次数。

输入输出样例

输入样例#1:
8
8 23 4 16 77 -5 53 100
输出样例#1:
5

---------------------------------------------------------------------------------------------------------------
本以为是逆序对,发现不一定相邻交换
找一条交换链,从原位置到新位置不停地走,最终会是一个环
注意每次加cnt-1,因为最后一次两个都到了正确位置
代码实现原位置封装结构体,排序,flag代表归位,走就行了
#include<iostream>
#include<cstdio> 
#include<algorithm>
using namespace std;
const int N=100005;

struct node{
    int o,w;
}a[N];
bool cmp(const node &a,const node &b){
    return a.w<b.w;
}
int n,flag[N],ans=0;    //guiwei
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i].w); a[i].o=i;
    }
    sort(a+1,a+1+n,cmp);
    for(int i=1;i<=n;i++){
        if(flag[i]==0){
            int now=i,cnt=0;
            while(flag[now]==0){
                cnt++;
                flag[now]=1;
                now=a[now].o;
            }
            ans+=cnt-1;
        }
    }
    cout<<ans;
}

 

 2.P1630求和

题目描述

求1^b+2^b+……+a^b的和除以10000的余数。

输入输出格式

输入格式:

第一行包含一个正整数N,表示共有N组测试数据;

接下来N行,每行包含两个正整数a和b。

【数据规模】

对于30%的数据中,满足N<=10,a,b<=1000;

对于100%的数据中,满足N<=100,a,b<=1000000000;

输出格式:

共N行,每行一个对应的答案。

输入输出样例

输入样例#1:
1
2 3
输出样例#1:
9
------------------------------------------------------------------------------------------
暴力只能拿30分
用f[i]表示i^b%10000的结果,考虑每个fi对答案的贡献即可
复杂度O(10000*logb*N)
不用long long也可以
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int MOD=10000,N=10005;
typedef long long ll;
int n;
ll a,b;
ll f[N];

ll powMod(ll a,ll b){
    ll ans=1;
    for(;b;b>>=1,a=(a*a)%MOD)
        if(b&1) ans=(ans*a)%MOD;
    return ans;
}
ll solve(ll a,ll b){
    for(int i=1;i<=MOD;i++)
        f[i]=powMod(i,b);
    ll div=a/MOD,mod=a%MOD;
    ll ans=0;
    for(int i=1;i<=MOD;i++){
        ans=(ans+div*f[i])%MOD;
        if(i<=mod) ans=(ans+f[i])%MOD;
    }
    return ans;
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        memset(f,0,sizeof(f));
        scanf("%lld%lld",&a,&b);
        cout<<solve(a,b)<<"\n";
    }
}

 

 3.P1403约数研究

题目描述

科学家们在Samuel星球上的探险得到了丰富的能源储备,这使得空间站中大型计算机“Samuel2”的长时间运算成为了可能。由于在去年一年的辛苦工作取得了不错的成绩,小联允许用“Samuel2”进行数学研究。

小联最近在研究和约数有关的问题,他统计每个正数N的约数的个数,并以f(N)来表示。现在小联希望用“Samuel2”来统计f(1)到f(N)的累加和M。

f(n)表示n的约数个数,现在给出n,要求求出f(1)到f(n)的总和。

输入输出格式

输入格式:

输入一行,一个整数n

输出格式:

输出一个整数,表示总和

输入输出样例

输入样例#1:
3
输出样例#1:
5
------------------------------------
一开始想用唯一分解加约数个数然和求和
看到是求1~n,能不能像筛法那样,突然一想,考虑每个数的贡献不就是n/i,太水了,━━( ̄ー ̄*|||━━
#include<iostream>
using namespace std;
int n,ans=0;
int main(){
    cin>>n;
    for(int i=1;i<=n;i++) ans+=n/i;
    cout<<ans;
} 

 

 
 

 

洛谷数论{水题}集合

标签:

原文地址:http://www.cnblogs.com/candy99/p/5767875.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!