hdu4407容斥原理

来源:互联网 发布:淘宝页面图片 编辑:程序博客网 时间:2024/05/18 02:11

题意:
有一个元素为 1~n 的数列{An},有2种操作(1000次):
1、求某段区间 [a,b] 中与 p 互质的数的和。
2、将数列中某个位置元素的值改变。

import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.io.PrintWriter;import java.io.StreamTokenizer;import java.math.BigInteger;import java.util.ArrayList;import java.util.Arrays;import java.util.Collection;import java.util.Collections;import java.util.Comparator;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.LinkedList;import java.util.Map;import java.util.NavigableSet;import java.util.PriorityQueue;import java.util.Queue;import java.util.Scanner;import java.util.Set;import java.util.SortedSet;import java.util.Stack;import java.util.StringTokenizer;import java.util.TreeSet;public class Main {    public static void main(String[] args) throws IOException{           StreamTokenizer cin = new StreamTokenizer(new BufferedInputStream(System.in));            InputReader in = new InputReader(System.in)  ;           PrintWriter out = new PrintWriter(System.out) ;           int t = in.nextInt() ;           for(int i = 1 ; i <= t ; i++){                new Task().solve(in, out)  ;  // out.flush() ;           }           out.flush() ;     }}class  Task{       static int N = 700 ;       static int[] prime = new int[N] ;       static int pid = 0 ;       static boolean[] vis = new boolean[N] ;       static{             for(int i = 2 ; i < N ; i++){                  if(! vis[i]) prime[pid++] = i ;                  for(int j = 0 ; j < pid && prime[j] * i < N ; j++){                          vis[i * prime[j]] = true ;                          if(i % prime[j] == 0) break ;                  }             }       }       int  gcd(int x , int y){            return y == 0 ? x : gcd(y , x%y) ;        }       HashMap<Integer, Integer> hash = new HashMap<Integer, Integer>() ;       ArrayList<Integer> factor = new ArrayList<Integer>() ;       long  sigma(long n){             return (n + 1 ) * n / 2 ;       }       long  sum(int n){             long ans = sigma(n) ;             int m = factor.size() ;             int limit = 1<<m ;             for(int i = 1 ; i < limit ; i++){                  int k = 0 ;                  int val = 1 ;                  for(int j = 0 ; j < m ; j++){                       if((i & (1<<j)) > 0){                            k++ ;                            val *= factor.get(j)  ;                       }                  }                  long t = sigma(n/val) * val ;                  if((k&1) > 0) ans -= t ;                  else ans += t ;             }             return ans ;       }       long  ask(int left , int right , int p){                 int n = p ;             factor.clear();             for(int i = 0 ; i < pid && prime[i]*prime[i] <= n ; i++){                   if(n % prime[i] == 0){                        while(n % prime[i] == 0) n /= prime[i] ;                        factor.add(prime[i]) ;                   }             }             if(n != 1) factor.add(n) ;             long ans = sum(right) - sum(left-1) ;             for(Map.Entry<Integer, Integer> e : hash.entrySet()){                   int id = e.getKey() ;                   int val = e.getValue() ;                   if(left <= id && id <= right){                         if(gcd(id , p) == 1) ans -= id ;                         if(gcd(val ,p) == 1) ans += val ;                   }             }             return ans ;       }       public void solve(InputReader in , PrintWriter out) throws IOException{              int n = in.nextInt() ;              int m = in.nextInt() ;              while(m-- > 0){                    if(in.nextInt() == 1)                         out.println(ask(in.nextInt() , in.nextInt() , in.nextInt())) ;                    else  hash.put(in.nextInt(), in.nextInt()) ;              }       }}class   InputReader{        public BufferedReader  reader;        public StringTokenizer  tokenizer;        public InputReader(InputStream stream){               reader = new BufferedReader(new InputStreamReader(stream), 32768) ;               tokenizer = null ;        }        public String next(){               while(tokenizer == null || ! tokenizer.hasMoreTokens()){                   try{                        tokenizer = new StringTokenizer(reader.readLine());                   }catch (IOException e){                        throw new RuntimeException(e);                   }               }               return tokenizer.nextToken();          }        public int  nextInt(){               return Integer.parseInt(next());        }        public long nextLong(){               return Long.parseLong(next());        }        public double nextDouble(){               return  Double.parseDouble(next());        }}
0 0