zoukankan      html  css  js  c++  java
  • hdu4407 Sum 容斥原理

    XXX is puzzled with the question below: 

    1, 2, 3, ..., n (1<=n<=400000) are placed in a line. There are m (1<=m<=1000) operations of two kinds.

    Operation 1: among the x-th number to the y-th number (inclusive), get the sum of the numbers which are co-prime with p( 1 <=p <= 400000).
    Operation 2: change the x-th number to c( 1 <=c <= 400000).

    For each operation, XXX will spend a lot of time to treat it. So he wants to ask you to help him.

    容斥原理

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<algorithm>
     4 #include<math.h>
     5 using namespace std;
     6 typedef long long ll;
     7 
     8 const int maxn=4e5+5;
     9 
    10 inline int gcd(int a,int b){return b?gcd(b,a%b):a;}
    11 
    12 int ori[1005],cha[1005];
    13 int pnum[50],num;
    14 
    15 int main(){
    16     int T;
    17     scanf("%d",&T);
    18     while(T--){
    19         int n,m;
    20         scanf("%d%d",&n,&m);
    21         int cnt=0;
    22         while(m--){
    23             int f;
    24             scanf("%d",&f);
    25             if(f==1){
    26                 int x,y,p;
    27                 scanf("%d%d%d",&x,&y,&p);
    28                 int tmp=p;
    29                 num=0;
    30                 for(int i=2;i*i<=tmp;++i){
    31                     if(!(tmp%i)){
    32                         pnum[++num]=i;
    33                         tmp/=i;
    34                         while(!(tmp%i))tmp/=i;
    35                     }
    36                 }
    37                 if(tmp>1)pnum[++num]=tmp;
    38                 ll ans=0;
    39                 for(int i=1;i<(1<<num);++i){
    40                     int bit=0;
    41                     ll mul=1;
    42                     for(int j=1;j<=num;++j){
    43                         if(i&(1<<(j-1))){
    44                             bit++;
    45                             mul*=pnum[j];
    46                         }
    47                     }
    48                     ll tmp=y/mul-(x-1)/mul;
    49                     ll l=((x-1)/mul+1)*mul,r=y/mul*mul;
    50                     tmp=(l+r)*tmp/2;
    51                     if(bit%2)ans+=tmp;
    52                     else ans-=tmp;
    53                 }
    54                 ans=(x+y)*(ll)(y-x+1)/2-ans;
    55                 for(int i=1;i<=cnt;++i){
    56                     if(ori[i]>=x&&ori[i]<=y){
    57                         int gcd1=gcd(ori[i],p),gcd2=gcd(cha[i],p);
    58                         if(gcd1==1&&gcd2>1)ans-=ori[i];
    59                         else if(gcd1>1&&gcd2==1)ans+=cha[i];
    60                         else if(gcd1==1&&gcd2==1)ans=ans-ori[i]+cha[i];
    61                     }
    62                 }
    63                 printf("%lld
    ",ans);
    64             }
    65             else{
    66                 int x,c;
    67                 scanf("%d%d",&x,&c);
    68                 bool f=1;
    69                 for(int i=1;i<=cnt;++i){
    70                     if(ori[i]==x){
    71                         cha[i]=c;
    72                         f=0;
    73                         break;
    74                     }
    75                 }
    76                 if(f){
    77                     ++cnt;
    78                     ori[cnt]=x;
    79                     cha[cnt]=c;
    80                 }
    81             }
    82         }
    83     }
    84     return 0;
    85 }
    View Code
  • 相关阅读:
    ResNet & DenseNet
    82. 删除排序链表中的重复元素 II
    C++ Primer 笔记——多重继承与虚继承
    C++ Primer 笔记——命名空间
    C++ Primer 笔记——异常处理
    C++ Primer 笔记——模板与泛型编程
    C++ Primer 笔记——转发
    C++ Primer 笔记——理解std::move
    C++ Primer 笔记——OOP
    C++ Primer 笔记——重载运算
  • 原文地址:https://www.cnblogs.com/cenariusxz/p/6598191.html
Copyright © 2011-2022 走看看