zoukankan      html  css  js  c++  java
  • HDU

    题意:初始序列[1..N](1<=N<=4e5),支持两种操作:1.求区间[x,y]内与p互素的数之和; 2。将x位置的数变为c。

    分析:很容易把人骗到线段树的思维中,而实际上操作2单点的修改可以用map去记录,之后统计和的时候再去检查是否有给定区间内的数被修改。

    区间[x,y]内与p互素的数之和,可以转化成求与p不互素的数之和。设p的质因子有[f1,f2...fk],则若干个质因子积的倍数一定不与p互素,用容斥求出在[x,y]区间内与p的质因子积的倍数。根据等差数列求和算出[x,y]区间的和,并检查区间内被修改的值,若原值与p互素,则要减去;若修改后的值与p互素,则要加上。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 4e5+5;
    typedef long long LL;
    map<int,int> vz;
    
    LL gcd(LL a,LL b)
    {
        if(b==0) return a;
        return gcd(b,a%b);
    }
    
    LL sum1(LL a1,LL an)         //等差数列求和
    {
        LL n  = an-a1+1;
        LL res = (a1 + an) * n / 2;
        return res;    
    }
    
    LL sum2(LL l,LL r,LL val)     //等比数列求和
    {
        int n = ( r / val ) - ( ( l - 1 ) / val ) ;
        int a1 = ( l % val == 0 )? l : ( val - l % val ) + l ;
        int an = r - r % val ;
        LL res = (LL)( a1 + an ) * (LL)n / 2 ; 
        return res;
    }
    
    LL cal(int l,int r,int p)
    {
        vector<int> fac;
        int tmp = p;
        for(int i=2;i*i<=tmp;++i){
            if(tmp%i==0){
                fac.push_back(i);
                while(tmp%i==0) tmp/=i;
            }
        }
        if(tmp>1) fac.push_back(tmp);
        int cnt = fac.size();
        int up = 1<<cnt;
        LL res=0;
        for(int i=1;i<up;++i){                          //容斥统计与p不互素的数的和
            int bits = 0 ;
            LL ji = 1;
            for(int j=0;j<cnt;++j){
                if(i&(1<<j)){
                    bits++;
                    ji *= fac[j];
                }
            }
            LL sum= sum2(l,r,ji);
            if(bits &1) res+=sum;
            else res-=sum;         
        }
        res = sum1(l,r)-res;
        for(auto &v :vz){
            if(v.first<l) continue;
            if(v.first>r) break;
            if(gcd(v.first,p)==1) res-=v.first;         //多加了要减去
            if(gcd(v.second,p)==1) res+=v.second;       //修改后的结果与p互质,加上
        }
        return res; 
    }
    
    int main()
    {
        #ifndef ONLINE_JUDGE
            freopen("in.txt","r",stdin);
            freopen("out.txt","w",stdout);
        #endif
        int T; scanf("%d",&T);
        while(T--){
            int N,M; scanf("%d%d",&N,&M);
            vz.clear();
            int op,x,y,p,c;
            while(M--){
                scanf("%d",&op);
                if(op==1){
                    scanf("%d%d%d",&x,&y,&p);
                    if(x>y) swap(x,y);
                    printf("%lld
    ",cal(x,y,p));
                }
                else{
                    scanf("%d%d",&x,&c);
                    vz[x] =c;                   //记录修改
                }
            }
        }
        return 0;
    }
    为了更好的明天
  • 相关阅读:
    hive sql常用整理-hive引擎设置
    hdfs数据到hbase过程
    phoenix表操作
    HBase describe table 参数说明
    HBase 常用Shell命令
    sqoop的基本语法详解及可能遇到的错误
    Linux maven 下 jar包下载不下来的解决方法
    Linu 修改maven的setting保护文件
    Mybatis generator 自动生成代码
    Springmvc mvc:exclude-mapping不拦截 无效
  • 原文地址:https://www.cnblogs.com/xiuwenli/p/9510006.html
Copyright © 2011-2022 走看看