also seems like those greedy tags are quite greedy for space 
| # | User | Rating |
|---|---|---|
| 1 | jiangly | 3810 |
| 2 | Benq | 3676 |
| 3 | Kevin114514 | 3655 |
| 4 | maroonrk | 3463 |
| 5 | strapple | 3447 |
| 6 | Um_nik | 3387 |
| 7 | heuristica | 3322 |
| 8 | turmax | 3317 |
| 9 | tourist | 3307 |
| 10 | jiangbowen | 3291 |
| # | User | Contrib. |
|---|---|---|
| 1 | Qingyu | 156 |
| 2 | nik_exists | 150 |
| 2 | maspy | 150 |
| 4 | Um_nik | 143 |
| 5 | Errichto | 139 |
| 6 | adamant | 137 |
| 7 | AmShZ | 135 |
| 8 | maroonrk | 133 |
| 9 | BledDest | 132 |
| 10 | qwexd | 129 |
also seems like those greedy tags are quite greedy for space 
Anyways, I have indeed done the swap to cpp and it is so fast! In java, I had my normal b-tree solution, but I had to go through the hell of writing the ceil function this time for it. Unfortunately, despite all my optimizations, I was unable to ac all the test cases on traffic on cses. I really pulled out all the stops. Anyways, literally just transcribing it to cpp almost line for line allowed it to comfortably slide under the 1 second bounds. Anyways, I digress. Since then, I've been on a cpp high and for some inexplicable reason, my stupid ahh thought it would be a good idea to turn the general k-killer josephus problem into O(n). At first I was going to start domestically abusing the CPU and force it to reveal the n-th bit of a 200000 bit string, but unfortunately, I think cses is all out of x200000 CPUs. I instead had to settle for a 3 layer prefix sum lookup table solution which unfortunately scales badly, but is quite good for n <= 2e5. All of those static casts are quite necessary!!!! I don't like the yellow squigglies that clang gives me! Unfortunately for me, I somehow as a god at fucking up in the most unnoticeable way and was actually doing my bitshifts inverted! I spent a sad 3 hours debugging that. But that's all in the past now, and it is the most glorious code you've ever laid your eyes upon.
Anyways, the macro and var names are obviously the greatest you've ever seen. Tell me how I should optimize this more! I think it might be possible to parallelize it with vectorization and bitshifts for a 4x speed up on the initial construction of the prefix sums. Obviously, I could probably directly set the prefix sums instead of using a few methods to build it up, but where's the fun in that?
#include <iostream>
using namespace std;
#define tinyuwublock 16
#define numtinyuwus 16384
#define uwusperowo 256
#define numowos 64
#define owospermegauwu 16
#define nummegauwus 4
uint16_t bitvector[numtinyuwus];
uint16_t uwucounts[numtinyuwus];
uint32_t owoprefix[numowos+1];
uint32_t megauwuprefix[nummegauwus+1];
uint8_t lut[65536][16];
void buildluts() {
for (int i = 0; i < 65536; ++i) {
int c = 0;
for (int b = 0; b < 16; ++b) {
if (i & (1 << b)) {
lut[i][c++] = b;
}
}
for (int b = c; b < 16; ++b) {
lut[i][b] = 255;
}
}
}
void repairprefix() {
for (int i = 0; i < numtinyuwus; ++i) {
uwucounts[i] = __builtin_popcount(bitvector[i]);
}
owoprefix[0] = 0;
for (int i = 0; i < numowos; ++i) {
uint32_t sum = 0;
int start = i * uwusperowo;
for (int j = 0; j < uwusperowo; ++j) {
sum += uwucounts[start + j];
}
owoprefix[i+1] = owoprefix[i] + sum;
}
megauwuprefix[0] = 0;
for (int i = 0; i < nummegauwus; ++i) {
uint32_t s = 0;
int st = i * owospermegauwu;
for (int j = 0; j < owospermegauwu; ++j) {
s+= owoprefix[st + j + 1] - owoprefix[j + st];
}
megauwuprefix[i+1] = megauwuprefix[i] + s;
}
}
int select1(uint32_t n) {
int muwu = 0;
while (megauwuprefix[muwu + 1] < n) ++muwu;
n -= megauwuprefix[muwu];
int owo = muwu * owospermegauwu;
while (owoprefix[owo + 1] - megauwuprefix[muwu] < n) ++owo;
n -= (owoprefix[owo] - megauwuprefix[muwu]);
int base = owo * uwusperowo;
int i = 0;
while (uwucounts[base + i] < n) {
n -= uwucounts[base + i];
++i;
}
int idx = base + i;
return idx * tinyuwublock + lut[bitvector[idx]][n - 1];
}
void flip(int n) {
int uwu = n/tinyuwublock;
int off = n%tinyuwublock;
int q = ((bitvector[uwu] >> off) & 1) ? -1 : 1;
bitvector[uwu] ^= (1 << off);
uwucounts[uwu] += q;
int owo = uwu / uwusperowo;
for (int i = owo+1; i <= numowos; ++i) {
if (q == -1) owoprefix[i]-=1;
else owoprefix[i] += 1;
}
int muwu = owo / owospermegauwu;
for (int i = muwu+1; i <= nummegauwus; ++i) {
if (q == -1) megauwuprefix[i] -= 1;
else megauwuprefix[i] += 1;
}
}
int main() {
cin.tie(nullptr);
ios::sync_with_stdio(false);
int n;
cin >> n;
int k;
cin >> k;
++k;
int full_blocks = n / tinyuwublock;
for (int i = 0; i < full_blocks; ++i) bitvector[i] = 0xFFFF;
if (n % tinyuwublock) bitvector[full_blocks] = (1u << (n % tinyuwublock)) - 1;
uint32_t pos = 0;
int alive = n;
buildluts();
repairprefix();
while (alive != 0) {
pos = (static_cast<uint32_t>(pos) + static_cast<uint32_t>(k) - 1u) % static_cast<uint32_t>(alive);
int idx = select1(static_cast<uint32_t>(pos + 1u));
flip(idx);
--alive;
cout << idx +1 << ' ';
}
}
CSES time limits are actually so cancerous for java. I had to literally binary search for a viable max nodes for my Concert Tickets solution to work. However, in the end, my radix trie did indeed work! With 0.99 s on test case 5, I barely scrape by with another ac on these absolutely cancerous time constraints. If this didn't work, I was going to grab the FastIO from kattis and see if the few ms from that would save me. If that failed, then reading System.in.read(byte[]) would have to be my life.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;
public class ticketmeisterofconcert {
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(System.out);
Tokenizer tr = new Tokenizer(in.readLine());
IntegerMultiSetTree imst = new IntegerMultiSetTree();
int n = tr.intToken();
int m = tr.intToken();
int[] c = new int[m];
tr = new Tokenizer(in.readLine());
for (int i = 0; i < n; ++i) imst.add(tr.intToken());
tr = new Tokenizer(in.readLine());
for (int i = 0; i < m; ++i) c[i] = tr.intToken();
int[] pay = new int[m];
for (int i = 0; i < m; ++i) {
Integer q = imst.floor(c[i]);
pay[i] = q;
if (q != -1)imst.remove(q);
}
for (int uwu : pay) out.println(uwu);
out.flush();
}
static class Tokenizer extends StringTokenizer {
public Tokenizer(String in) { super(in); }
public int intToken() { return Integer.parseInt(this.nextToken()); }
public long longToken() { return Long.parseLong(this.nextToken()); }
public double doubleToken() { return Double.parseDouble(this.nextToken()); }
}
static class IntegerMultiSetTree {
static final int MAX_BITS = 30;
static final int MAX_NODES = 5_360_000;
int[] tree = new int[MAX_NODES*2];
int[] count = new int[MAX_NODES];
int ptr = 0;
public void add(int a) {
int t = 0;
for (int i = 0; i < MAX_BITS; ++i) {
int q = (a >>> MAX_BITS-1-i) & 1;
if (tree[t+q] == 0) {
tree[t+q] = 2 * ++ptr;
}
++count[t];
t = tree[t+q];
}
++count[t];
}
public void remove(int a) {
int t = 0;
--count[t];
for (int i = 0; i < MAX_BITS; ++i) {
int q = (a >>> MAX_BITS-1-i) & 1;
int n = tree[t+q];
if (--count[n] == 0) tree[t+q] = 0;
if (tree[t+q] == 0) {
return;
}
t = tree[t+q];
}
}
public int floor(int a) {
int[] t = new int[MAX_BITS+1];
return dfs(t, a, 0, 0);
}
private int dfs(int[] t, int a, int q, int uwu) {
if (q == MAX_BITS) return uwu;
for (int i = 1; i >= 0; --i) {
if (uwu + (i << MAX_BITS-1-q) <= a) {
if (tree[t[q]+i] == 0) continue;
t[q+1] = tree[t[q]+i];
int b;
if ((b = dfs(t, a, q+1, uwu + (i << MAX_BITS-1-q))) != -1) return b;
}
}
return -1;
}
}
}
| Name |
|---|


