您的位置:首页 > 其它

Codeforces 616E Sum Of Reminders

2016-01-14 20:22 330 查看
616传送门:http://codeforces.com/contest/616/problem/E

[code]刚开始那个判断条件写错了,即判断什么时候应该减掉,减的方法对了,但刚开始写的那个条件是永远都成立的,
if(ans[i-1].fi<m)

这样就导致了第一个样例总是多减掉,而实际应该是当m<n的时候减掉,这就说明自己想的时候是只按照那一种情况想的,应该跳出思维的局限性
写的时候卡了2处:
第一处为存因子的时候,由于对具体的过程没有想清楚,所以在*号里面的存储方式是错误的
比方说:
25
1 25
2 12
3 8
4 6
5 5
6 4
8 3
12 2
只有在根号N后面的才可以整体处理,而前面的则不行,因为越过根号N之后才能使后面的值保持不变,只有前面的基数足够大,才能使后面的商的结果不变,而只用因子那绝对是错的,下次应该在纸上模拟清楚之后再敲! ! !

第二处错误为每一步都要取一次模,实际操作的过程中在局部乘法的时候忘记取模了,导致最后出现了负值(一次加法不足以加到正数),还有坑点就是在整除2的位置处要判断哪一个是正好整除,一定要细致! ! !**

#include<bits/stdc++.h>
using  namespace std;
#define ll long long
#define pb push_back
#define mp make_pair
#define fi first
#define se second
const int maxn=1e3+10;
ll n,m;
const ll mod=1e9+7;
vector<pair<ll,ll>>ans;
void debug(){
    for(pair<ll,ll> x:ans){
        printf("%lld %lld\n",x.first,x.second);
    }
}
ll work(ll i,ll j){
   if((i+j)%2==0)
    return (((i+j)/2%mod)*((j-i+1)%mod))%mod;
   return (((i+j)%mod)*((j-i+1)/2%mod))%mod;
}
int main(){
    cin>>n>>m;
    ll sum=((n%mod)*(m%mod))%mod;
    for(ll i=1;i*i<=n;i++){
        ll tmp=n/i;
        ans.pb(mp(i,tmp));
        if(tmp!=i) ans.pb(mp(tmp,i));
        /*if(n%i==0){
            ans.pb(mp(i,n/i));
        }
        if(n!=i*i) ans.pb(mp(n/i,i));*/
    }
    ans.pb(mp(0,0));
    sort(ans.begin(),ans.end());
   //debug();
    int i;
    for(i=1;i<ans.size()&&ans[i].fi<=m;i++){
        sum=(sum-((work(ans[i-1].fi+1,ans[i].fi)*(ans[i].se%mod)))%mod+mod)%mod;
    }
    if(m<n){
        i--;
        sum=(sum-((work(ans[i].fi+1,m)*(ans[i+1].se%mod)))%mod+mod)%mod;
    }
    cout<<sum<<endl;
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: