QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#413682 | #2743. Seats | oolimry | 0 ✓ | 0ms | 0kb | C++14 | 4.2kb | 2024-05-17 21:07:03 | 2024-05-17 21:07:04 |
Judging History
answer
#include "seats.h"
#include <bits/stdc++.h>
using namespace std;
const long long inf = 1e9;
typedef pair<long long, int> ii;
int n, rows, cols;
static ii pos[1000005]; ///for each number, ii(r, c)
static vector<vector<int> > arr; ///arr[r*cols+c] is the element at (r,c)
///we build a grid such that the boundaries are filled with the number n
///Everything here is segment tree
static ii tree[2000005]; ///we store the minimum element, and the number of occurances
static long long lazy[2000005]; ///we store the minimum element, and the number of occurances
///helper function to update the value of node i from the children of i
inline void relax(int i){
if(tree[i<<1].first == tree[i<<1|1].first){
tree[i] = ii(tree[i<<1].first+lazy[i], tree[i<<1].second + tree[i<<1|1].second);
}
else{
tree[i] = min(tree[i<<1],tree[i<<1|1]);
tree[i].first += lazy[i];
}
}
void initSegment(){
for(int i = n;i < 2 * n;i++) tree[i] = ii(0,1);
for(int i = n - 1;i >= 0;i--) relax(i);
}
inline void update(int l, int r, long long v){
if(l == r) return;
int ll = l + n, rr = r - 1 + n;
for(l += n,r += n;l < r;l>>=1,r>>=1){
if(l&1){
tree[l].first += v;
lazy[l] += v;
l++;
}
if(r&1){
r--;
tree[r].first += v;
lazy[r] += v;
}
}
while(ll > 1){
ll >>= 1;
relax(ll);
}
while(rr > 1){
rr >>= 1;
relax(rr);
}
}
void prop(int i){
if(i != 1) prop(i >> 1);
tree[i<<1].first += lazy[i];
lazy[i<<1] += lazy[i];
tree[i<<1|1].first += lazy[i];
lazy[i<<1|1] += lazy[i];
lazy[i] = 0;
}
inline int query(){
prop((n) >> 1); ///propogate the 2 ends
prop((2*n-1) >> 1);
if(tree[1].first+lazy[1] == 4){
return tree[1].second;
}
else{
return 0;
}
}
///segment tree ends
///consider a 2x2 square whose top-left corner is at r, c
void makeUpdate(int r, int c, bool isUndo){
vector<int> values = {arr[r][c],arr[r+1][c],arr[r][c+1],arr[r+1][c+1]};
sort(values.begin(),values.end());
///if isReverse, we undo our previous update
if(isUndo){
update(values[0],values[1],-1);
update(values[2],values[3],-inf);
}
else{
update(values[0],values[1],1); ///add one to imply within that range, there is one more 2x2 square with exactly 1 black square
update(values[2],values[3],inf); ///add infinity to "ruin" that range. When there are 2 black squares in the 2x2 square, it's impossible to have beautiful rectangle
//cout << values[0] << " " << values[1] << " " << 1 << "\n";
//cout << values[2] << " " << values[3] << " " << "f" << "\n";
}
}
void give_initial_chart(int H, int W, vector<int> R, vector<int> C) {
n = H * W;
rows = H; cols = W;
for(int i = 0;i < rows+2;i++){
arr.push_back({});
arr.back().assign(cols+2,n);
}
for(int i = 0;i < n;i++){
R[i]++; C[i]++;
arr[R[i]][C[i]] = i;
pos[i] = ii(R[i],C[i]);
}
initSegment();
for(int r = 0;r <= rows;r++){
for(int c = 0;c <= cols;c++){
makeUpdate(r,c,false);
}
}
}
int swap_seats(int a, int b) {
ii aPos = pos[a]; ii bPos = pos[b];
//cout << aPos.first << " " << aPos.second << "\n";
//cout << bPos.first << " " << bPos.second << "\n";
///undo updates for all affected rectangles
makeUpdate(aPos.first-1,aPos.second-1,true);
makeUpdate(aPos.first,aPos.second-1,true);
makeUpdate(aPos.first-1,aPos.second,true);
makeUpdate(aPos.first,aPos.second,true);
makeUpdate(bPos.first-1,bPos.second-1,true);
makeUpdate(bPos.first,bPos.second-1,true);
makeUpdate(bPos.first-1,bPos.second,true);
makeUpdate(bPos.first,bPos.second,true);
///swapping the elements
pos[b] = aPos; pos[a] = bPos;
arr[aPos.first][aPos.second] = b; arr[bPos.first][bPos.second] = a;
///now update again for all affected rectangles
makeUpdate(aPos.first-1,aPos.second-1,false);
makeUpdate(aPos.first,aPos.second-1,false);
makeUpdate(aPos.first-1,aPos.second,false);
makeUpdate(aPos.first,aPos.second,false);
makeUpdate(bPos.first-1,bPos.second-1,false);
makeUpdate(bPos.first,bPos.second-1,false);
makeUpdate(bPos.first-1,bPos.second,false);
makeUpdate(bPos.first,bPos.second,false);
return query();
}
Details
Tip: Click on the bar to expand more detailed information
Subtask #1:
score: 0
Runtime Error
Test #1:
score: 0
Runtime Error
input:
3 3 5000 2 2 1 2 0 2 0 1 0 0 2 1 1 1 1 0 2 0 6 0 5 7 6 4 3 2 0 2 0 2 7 0 7 0 3 2 3 6 0 2 3 5 2 6 2 0 8 6 0 6 1 3 1 8 8 1 4 2 1 8 2 5 1 3 7 0 6 5 6 3 2 8 8 2 1 3 8 5 6 3 8 0 4 8 6 8 7 8 4 3 3 6 5 0 8 5 1 7 2 6 1 2 5 4 5 1 7 6 8 4 7 3 6 8 8 3 0 3 6 3 0 8 0 5 7 2 0 3 7 5 4 5 3 5 1 0 0 8 7 0 2 5 5 8 7 4...
output:
Unauthorized output
result:
Subtask #2:
score: 0
Skipped
Dependency #1:
0%
Subtask #3:
score: 0
Skipped
Dependency #1:
0%
Subtask #4:
score: 0
Runtime Error
Test #33:
score: 0
Runtime Error
input:
101 101 5000 0 0 0 1 0 2 0 3 0 4 0 5 0 6 0 7 0 8 0 9 0 10 0 11 0 12 0 13 0 14 0 15 0 16 0 17 0 18 0 19 0 20 0 21 0 22 0 23 0 24 0 25 0 26 0 27 0 28 0 29 0 30 0 31 0 32 0 33 0 34 0 35 0 36 0 37 0 38 0 39 0 40 0 41 0 42 0 43 0 44 0 45 0 46 0 47 0 48 0 49 0 50 0 51 0 52 0 53 0 54 0 55 0 56 0 57 0 58 0 ...
output:
Unauthorized output
result:
Subtask #5:
score: 0
Runtime Error
Test #44:
score: 0
Runtime Error
input:
1 3 50000 0 1 0 2 0 0 0 2 2 0 2 1 0 1 1 0 0 1 1 2 1 2 1 2 0 2 1 0 0 2 2 0 1 2 2 1 2 0 0 1 0 2 1 2 1 0 1 0 1 2 0 1 1 0 0 2 0 2 2 1 0 2 1 0 1 2 2 1 2 1 1 2 0 1 1 2 0 1 0 2 1 2 0 2 2 1 2 0 1 2 1 0 1 0 2 1 1 0 1 0 2 1 1 2 0 2 2 0 1 0 2 0 0 2 1 0 0 2 1 2 2 1 0 1 0 2 1 0 2 1 2 0 1 2 0 1 2 0 2 1 2 0 0 2 1 ...
output:
Unauthorized output
result:
Subtask #6:
score: 0
Skipped
Dependency #1:
0%