QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#188108#4887. Fast BridgesDualqwqWA 6ms31788kbC++144.9kb2023-09-25 15:04:362023-09-25 15:04:37

Judging History

你现在查看的是最新测评结果

  • [2023-09-25 15:04:37]
  • 评测
  • 测评结果:WA
  • 用时:6ms
  • 内存:31788kb
  • [2023-09-25 15:04:36]
  • 提交

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'