Блог пользователя DPR

Автор DPR, история, 3 года назад, По-английски

If anyone who was able to solve the problem tell me where my approach could've been optimized.

I took a map and put all scores which belong to university i in an array and stored it in the map against key i.

Then, I sorted the array for every key in the map, and transformed the array into prefix sum array.

My observation was that, say for university i, if the size of array against key i is not entirely divisible by k (k : 1 to n), then we have to ignore first k%n elements (n = size of array against key i in map), this translates to substraction of prefix sum at index k % n — 1 from entire sum of all students.

So basically, after this, I looped over all k (1 to n) and over all map keys, to find sizes which are indivisible by k and performed above operation.

This essentially gave me a TLE on test case 5.

I'd be really grateful for any tips/ help as to where I could further optimize this.

Thanks a lot.

HERE'S MY CODE:

public static void solve(int n, int[] u, long[] s){

Map<Integer,ArrayList<Long>> mp = new HashMap<>();

for(int i = 0 ; i < n ; i++){
  if(mp.containsKey(u[i]-1)){
    mp.get(u[i]-1).add(s[i]);
  }
  else{
    ArrayList<Long> ls = new ArrayList<>();
    ls.add(s[i]);
    mp.put(u[i]-1,ls);
  }
}

for(int i : mp.keySet()){
  Collections.sort(mp.get(i));
}

Long ans = 0l;
for(int i : mp.keySet()){
    for(long k : mp.get(i)){
      ans += k;
    }
}

for(int i : mp.keySet()){
  ArrayList<Long> ls = mp.get(i);
  for(int j = 1 ; j < ls.size() ; j++){
    ls.set(j,ls.get(j) + ls.get(j-1));
  }
}

Map<Integer,ArrayList<Integer>> sizes = new HashMap<>();

for(int k : mp.keySet()){
  if(sizes.containsKey(mp.get(k).size())){
    sizes.get(mp.get(k).size()).add(k);
  }
  else{
    ArrayList<Integer> ls = new ArrayList<>();
    ls.add(k);
    sizes.put(mp.get(k).size(),ls);
  }
}

System.out.print(ans + " ");
for(int i = 2 ; i <= n ; i++){
  long f = ans;
  for(int j : sizes.keySet()){
    if(j % i != 0){
      for(int k : sizes.get(j)){
          f -= mp.get(k).get((j % i)-1);
        }
      }
    }
  System.out.print(f + " ");
}
System.out.println("");

}

  • Проголосовать: нравится
  • -21
  • Проголосовать: не нравится

»
3 года назад, # |
  Проголосовать: нравится +3 Проголосовать: не нравится

I also used the same approach and got tle on testcase 4

»
3 года назад, # |
  Проголосовать: нравится +3 Проголосовать: не нравится

Instead of creating loop of k from 1 to n, create an array sum[n] which store the answer for index k now loop over all universities, taking k from 1 to the size of its student vector (no of students in university). accordingly adding values to sum array. here k is not from 1 to n hence time complexity is reduced. Thanks

  • »
    »
    3 года назад, # ^ |
    Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

    I think that taking k from 1 to size of its students reduces its complexity much, It becomes at most n*root(n). As, if the size of such universities is more than root(n), then their number will be less than root(n), so n*root(n) here and if the size of universities is less than root(n), then O(n) such universities can be there but k:1 to root(n) for such, so again n*root(n). So, overall complexity is n*root(n). The complexity might be less than this, but this was enough.

»
3 года назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

I did the same thing, except I exited out of the loop and printed out all $$$0$$$'s for the rest of the numbers once one of the answers was a $$$0$$$. That passed in 200ms with C++.