HDU 4407 Sum

来源:互联网 发布:万方—中国机构数据库 编辑:程序博客网 时间:2024/06/06 19:20

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4407


题意:有n个数,分别为1到n。
每次有两个操作:
1、求第x个数到第y个数范围内所有与p互质的数之和。
2、将第x个数的值改为c。


思路:由于操作小于1000,我们可以先记录所有的2操作(map),先用容斥查询一下,然后再去调整答案。


#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <cstdlib>#include <iostream>#include <algorithm>#include <stack>#include <map>#include <set>#include <vector>#include <sstream>#include <queue>#include <utility>using namespace std;#define rep(i,j,k) for (int i=j;i<=k;i++)#define Rrep(i,j,k) for (int i=j;i>=k;i--)#define Clean(x,y) memset(x,y,sizeof(x))#define LL long long#define ULL unsigned long long#define inf 0x7fffffff#define mod %100000007int T,n,m;//int a[1009]; // pos//int b[1009]; // valueint num;map<int,int> a;int gcd(int a,int b){    return (a%b==0)?b:gcd(b,a%b);}LL query(int n,int p){    int f[20];    int m = 0;    LL ans = n;    ans*=(n+1);    ans>>=1;    for(int i = 2; i*i <= p; i++)        if ( p % i == 0 )        {            f[m++] = i;            while( p % i == 0 ) p /= i;        }    if ( p > 1 ) f[m++] = p;    int uplim = 1<<m;    rep(i,1,uplim-1)    {        int cnt = 1;        int t = 0;        rep(j,0,m-1)        if ( i & (1<<j) )        {            cnt*=f[j];            t++;        }        int k = n/cnt;        if ( t & 1 ) ans -= (LL)cnt*(k+1)*k/2;        else ans += (LL)cnt*(k+1)*k/2;    }    return ans;}LL update(int x,int y,int p){    LL ans = 0;    map<int,int> ::iterator it = a.begin();    for( ; it != a.end() ; it++)        if ( (*it).first >=x && (*it).first <= y )        {            if ( gcd( (*it).first , p )==1 ) ans+=(*it).first;            if ( gcd( (*it).second , p )==1 ) ans-=(*it).second;        }    return ans;}int main(){    scanf("%d",&T);    while(T--)    {        scanf("%d%d",&n,&m);        int type,x,y,p;        //num = 0;        a.clear();        rep(i,1,m)        {            scanf("%d",&type);            if ( type == 2 )            {                scanf("%d %d",&x,&p);                //num++;                a[x] = p;                //b[num] = p;            }            else            {                scanf("%d%d%d",&x,&y,&p);                LL ans = query(y,p) - query(x-1,p);                ans-=update(x,y,p);                printf("%I64d\n",ans);            }        }    }    return 0;}


0 0
原创粉丝点击