2012 2012 ACM/ICPC Asia Regional Jinhua Online Sum

http://acm.hdu.edu.cn/showproblem.php?pid=4407

思路:问题转化:给定n,p,求n内和p互质的数的和。

剩下的暴力。

关键代码是队友写的:

View Code
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<map>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
map<int,int>as;
map<int,int>::iterator ps;
__int64 n,m,ans;
__int64 cnt1[10000],cnt2[10000];
__int64 zs[1000];
__int64 t1;
__int64 gcd(__int64 x,__int64 y){return y?gcd(y,x%y):x;}


bool cmp(__int64 a,__int64 b)
{  return abs(a)<abs(b);}
void chushi()
{
    zs[0]=2;
    __int64 i,j,len=1;
    for(i=3;i<=1000;i+=2)
    {
        for(j=0;zs[j]*zs[j]<i;j++)
            if(i%zs[j]==0) break;
        if(zs[j]*zs[j]>=i) zs[len++]=i;
    }
}
void fc(__int64 i,__int64 j,__int64 s)
{
    if(i==j)
    {
        cnt2[t1++]=s;
        return ;
    }
    fc(i+1,j,s);
    fc(i+1,j,s*cnt1[i]);
}
__int64 Sum(__int64 a,__int64 b,__int64 p)
{

    __int64 i,t,k;
        if(p==1) {
            return (a+b)*(b-a+1)/2;
        }
        t=0;
        for(i=0;zs[i]*zs[i]<=p;i++)
        if(p%zs[i]==0){
            cnt1[t++]=-zs[i];
            while(p%zs[i]==0) p/=zs[i];
        }
        if(p>1) cnt1[t++]=-p;
        t1=0;
        fc(0,t,1);
        sort(cnt2,cnt2+t1,cmp);
        cnt2[t1]=b+1;
        a--;
        __int64 aa=0,bb=0;
        for(i=0;abs(cnt2[i])<=a;i++)
        {
            k=a/abs(cnt2[i]);
            aa+=k*(k+1)/2*cnt2[i];
        }
        for(i=0;abs(cnt2[i])<=b;i++)
        {
            k=b/abs(cnt2[i]);
            bb+=k*(k+1)/2*cnt2[i];
        }
        return bb-aa;
}
int main()
{
    __int64 t,i,l,r,p,c;
    chushi();
    scanf("%I64d",&t);
    while(t--){
        scanf("%I64d%I64d",&n,&m);
        as.clear();
        while(m--){
            scanf("%I64d",&i);
            if(i==1){
                scanf("%I64d %I64d %I64d",&l,&r,&p);
                ans = Sum(l,r,p);
                for(ps=as.begin(); ps!=as.end(); ps++)
                    if(ps->first>=l && ps->first<=r){
                        if(gcd(ps->first,p)==1)ans -= ps->first;
                        if(gcd(ps->second,p)==1)ans += ps->second;
                    }
                    printf("%I64d\n",ans);
            }else{
                scanf("%I64d %I64d",&i,&c);
                as[i]=c;
            }
        }
    }
    return 0;
}

posted on 2012-09-22 18:36  aigoruan  阅读(243)  评论(0)    收藏  举报

导航