/** * Solution to Elven Efficiency * @author Melanie Kirsche */ import java.util.*; import java.io.*; public class ElvenEfficiency_mkirsche { public static void main(String[] args) throws IOException { FastScanner input = new FastScanner(System.in); int n = input.nextInt(), m = input.nextInt(); int[] pileSizes = new int[n]; for(int i = 0; i[] todo; @SuppressWarnings("unchecked") StoneGame(int[] piles, int[] queries) { this.piles = piles; this.queries = queries; // Get the maximum reachable pile size, which is the highest initial // pile size plus the number of queries int maxPile = 0; for(int x : piles) maxPile = Math.max(maxPile, x); // Initialize data structures dl = new DivList(maxPile + queries.length); todo = new Queue[maxPile + queries.length + 1]; for(int i = 0; i(); } frequencies = new long[maxPile + queries.length + 1]; // Update frequency and todo lists based on initial piles for(int x : piles) { if(frequencies[x] == 0) { int[] divisors = dl.getDivisors(x); for(int d : divisors) { todo[d].add(x); } } frequencies[x]++; } // Process queries one by one for(int q : queries) { processQuery(q); } } /* * Process a number being called out by adding one stone to each pile whose * size is a multiple of q */ void processQuery(int q) { /* * If q is bigger than any attainable value, do nothing */ if(q >= todo.length) { return; } /* * Iterate over all multiples of q and update piles of that size */ while(!todo[q].isEmpty()) { int pileSize = todo[q].poll(); long pileCount = frequencies[pileSize]; if(pileCount == 0) continue; // Ignore if no piles of this size if(frequencies[pileSize+1] == 0) { // If this is the first pile of size (pileSize+1), // then add (pileSize+1) to the list for each of its divisors int[] nextDivisors = dl.getDivisors(pileSize+1); for(int d : nextDivisors) { todo[d].add(pileSize+1); } } // Update pile size frequencies frequencies[pileSize+1] += pileCount; frequencies[pileSize] = 0; // Update answer stonesNeeded += pileCount; } } } /* * For each number all its divisors besides 1 */ static class DivList { int n; int[][] divisors; int[] count; DivList(int n) { this.n = n; divisors = new int[n+1][1]; count = new int[n+1]; for(int i = 2; i<=n; i++) { for(int j = i; j<=n; j+=i) { if(count[j] == divisors[j].length) { int[] nd = new int[2*divisors[j].length]; for(int k = 0; k