QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#188108 | #4887. Fast Bridges | Dualqwq | WA | 6ms | 31788kb | C++14 | 4.9kb | 2023-09-25 15:04:36 | 2023-09-25 15:04:37 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
const int N = 5e2 + 5,P = 998244353,inv3 = (P + 1) / 3;
typedef pair<int,int> pii;
#define FI first
#define SE second
inline void Plus(int &x,const int &y) { x += y;if(x >= P) x -= P;}
int n,K;
struct Bridge {
int x1,y1,x2,y2;
Bridge(){}
bool operator < (const Bridge &rhs) const { return x2 < rhs.x2;}
};
Bridge p[N];
bool Trans1(const Bridge &i,const Bridge &j) {
return i.x2 <= j.x1 && i.y2 <= j.y1;
}
bool Trans2(const Bridge &i,const Bridge &j) {
return i.x2 <= j.x1 && i.y2 >= j.y1;
}
int dp[N][N];
int val1[N << 1],len1;
int val2[N << 1],len2;
int f[2][N << 1][N]; // f_{x,y,i}
vector<pii> Poi[N]; // x2 升序
vector<int> brs[N << 1][N << 1];
int Area; // 2-side 矩形面积并
int LowY; // Y 的最值
Bridge p1[N],p2[N];
int n1,n2;
inline int Solve1() {
for(int i = 1;i <= n1;i++)
for(int j = 1;j <= n1;j++) dp[i][j] = 0;
for(int i = 1;i <= n1;i++) dp[i][i] = 1;
for(int len = 2;len <= n1;len++)
for(int i = 1;i + len - 1 <= n1;i++) {
int j = i + len - 1;
if(!Trans1(p1[i],p1[j])) continue;
dp[i][j] = 2;
for(int k = i + 1;k < j;k++)
if(Trans1(p1[i],p1[k]) && Trans1(p1[k],p1[j]))
dp[i][j] = max(dp[i][j],dp[i][k] + dp[k][j] - 1);
}
for(int i = 1;i <= len1;i++)
for(int j = 1;j <= len2;j++) brs[i][j].clear();
for(int i = 1;i <= n1;i++)
brs[p1[i].x1][p1[i].y1].push_back(i);
memset(f,0,sizeof f);
int ans = 0;
for(int x = len1 - 1;x >= 1;x--) {
for(int y = 1;y <= len2;y++)
for(int i = 1;i <= n1;i++) f[x&1][y][i] = 0;
for(int y = len2 - 1;y >= 1;y--) {
for(int i = 1;i <= n1;i++) {
f[x & 1][y][i] = max(f[x & 1][y + 1][i],f[(x+1) & 1][y][i]);
for(auto id : brs[x][y])
f[x & 1][y][i] = max(f[x & 1][y][i],dp[id][i]);
// printf("f[%d][%d][%d]=%d\n",x,y,i,f[x&1][y][i]);
}
for(int i = 0;i <= n1;i++) Poi[i].clear();
for(int i = 1;i <= n1;i++)
if(f[x & 1][y][i])
Poi[f[x & 1][y][i]].emplace_back(val1[p1[i].x2],val2[p1[i].y2]);
for(int t = 1;t <= n1;t++) {
Area = 0;LowY = K + 1;
for(auto it : Poi[t])
if(it.SE < LowY)
Plus(Area,1ll * (LowY - it.SE) * (K - it.FI + 1) % P),
LowY = it.SE;
Plus(ans,1ll * Area * (val1[x] - val1[x - 1]) % P * (val2[y] - val2[y - 1]) % P);
}
}
}
// printf("ans:%d\n",ans);
return ans;
}
inline int Solve2() {
for(int i = 1;i <= n2;i++) for(int j = 1;j <= n2;j++) dp[i][j] = 0;
for(int i = 1;i <= n2;i++) dp[i][i] = 1;
for(int len = 2;len <= n2;len++)
for(int i = 1;i + len - 1 <= n2;i++) {
int j = i + len - 1;
if(!Trans2(p2[i],p2[j])) continue;
dp[i][j] = 2;
for(int k = i + 1;k < j;k++)
if(Trans2(p2[i],p2[k]) && Trans2(p2[k],p2[j]))
dp[i][j] = min(dp[i][j],dp[i][k] + dp[k][j] - 1);
}
for(int i = 1;i <= len1;i++)
for(int j = 1;j <= len2;j++)
brs[i][j].clear();
for(int i = 1;i <= n2;i++)
brs[p2[i].x1][p2[i].y1].emplace_back(i);
memset(f,0,sizeof f);
int ans = 0;
for(int x = len1 - 1;x >= 1;x--) {
for(int y = 1;y <= len2;y++)
for(int i = 1;i <= n2;i++) f[x & 1][y][i] = 0;
for(int y = 1;y < len2;y++) {
for(int i = 1;i <= n2;i++) {
f[x & 1][y][i] = max(f[(x+1)&1][y][i],f[x & 1][y - 1][i]);
for(auto id : brs[x][y])
f[x & 1][y][i] = max(f[x & 1][y][i],dp[id][i]);
}
for(int i = 1;i <= n2;i++) Poi[i].clear();
for(int i = 1;i <= n2;i++)
if(f[x & 1][y][i]) Poi[f[x & 1][y][i]].emplace_back(val1[p2[i].x2],val2[p2[i].y2]);
for(int t = 1;t <= n2;t++) {
Area = 0;LowY = 0;
for(auto it : Poi[t])
if(it.SE > LowY)
Plus(Area,1ll * (it.SE - LowY) * (K - it.FI + 1) % P),
LowY = it.SE;
Plus(ans,1ll * Area * (val1[x] - val1[x - 1]) % P * (val2[y + 1] - val2[y]) % P);
}
}
}
// printf("ans:%d\n",ans);
return ans;
}
int main() {
cin >> n >> K;
for(int i = 1;i <= n;i++)
cin >> p[i].x1 >> p[i].y1 >> p[i].x2 >> p[i].y2;
sort(p + 1,p + n + 1);
for(int i = 1;i <= n;i++) val1[++len1] = p[i].x1,val1[++len1] = p[i].x2;
val1[++len1] = K + 1;
sort(val1 + 1,val1 + len1 + 1);
len1 = unique(val1 + 1,val1 + len1 + 1) - val1 - 1;
for(int i = 1;i <= n;i++) val2[++len2] = p[i].y1,val2[++len2] = p[i].y2;
val2[++len2] = K + 1;
sort(val2 + 1,val2 + len2 + 1);
len2 = unique(val2 + 1,val2 + len2 + 1) - val2 - 1;
auto idX = [&](const int &t) { return lower_bound(val1 + 1,val1 + len1 + 1,t) - val1;};
auto idY = [&](const int &t) { return lower_bound(val2 + 1,val2 + len2 + 1,t) - val2;};
for(int i = 1;i <= n;i++)
p[i].x1 = idX(p[i].x1),p[i].x2 = idX(p[i].x2),
p[i].y1 = idY(p[i].y1),p[i].y2 = idY(p[i].y2);
for(int i = 1;i <= n;i++)
if(p[i].y1 < p[i].y2) p1[++n1] = p[i];
else p2[++n2] = p[i];
int ans = 1ll * K * K % P * K % P * K % P * (K + 1) % P;
Plus(ans,P - 1ll * K * K % P * K % P * (K + 1) % P * (K + K + 1) % P * inv3 % P);
Plus(ans,P - Solve1());
Plus(ans,P - Solve2());
cout << ans << endl;
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 4ms
memory: 31580kb
input:
2 2 1 1 2 2 1 2 2 1
output:
6
result:
ok answer is '6'
Test #2:
score: 0
Accepted
time: 3ms
memory: 31580kb
input:
0 1000000000
output:
916520226
result:
ok answer is '916520226'
Test #3:
score: 0
Accepted
time: 0ms
memory: 31664kb
input:
5 5 1 1 3 3 3 3 5 1 3 3 4 5 3 3 5 4 1 5 3 3
output:
946
result:
ok answer is '946'
Test #4:
score: -100
Wrong Answer
time: 6ms
memory: 31788kb
input:
200 5 1 1 4 2 2 5 4 4 2 3 4 2 2 4 3 5 1 4 4 2 2 5 4 2 1 2 4 4 1 2 2 4 1 4 5 1 3 4 5 1 4 2 5 1 2 2 5 4 3 2 5 1 3 1 5 2 4 2 5 3 1 3 5 1 3 4 4 5 2 2 4 3 2 3 5 4 1 4 5 3 2 2 3 1 2 5 3 3 1 1 5 3 4 4 5 5 1 3 4 4 4 3 5 1 2 3 3 4 3 4 4 2 1 4 4 5 2 1 4 4 1 3 5 2 1 1 3 3 1 5 3 1 1 1 3 5 1 4 3 5 4 5 5 4 1 1 4 ...
output:
718
result:
wrong answer expected '708', found '718'