题解 挖掘机

传送门

首先贪心的思路很好想
然后发现如果有 \(>k\) 的空缺,贪心的部分会断掉
所以可以分成几块,二分出询问的区间包含了哪些段
但是只包含了一部分的不好处理

于是换个思路,考虑倍增优化贪心覆盖
考场上因为倍增的时候跳出边界了没跳出来炸掉了
考完拿拍造了几百组数据面向数据调试过了

Code:
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 100010

int h, w, k, q;
char s[N];
bool mp[13][N];

namespace force{
	void solve() {
		for (int i=1,d,l,r; i<=q; ++i) {
			int ans=0;
			scanf("%d%d%d", &d, &l, &r);
			for (int t=1; t<=d; ++t) {
				int lst=-1;
				for (int j=l; j<=r; ++j) if (mp[t][j]) {
					if (lst==-1 || j>lst+k-1) ++ans, lst=j;
				}
			}
			printf("%d\n", ans);
		}
		exit(0);
	}
}

namespace task1{
	int pre[13][N], suf[13][N], siz[13], sum[13][N];
	struct range{
		int l, r, val;
		range(){}
		range(int a, int b) {l=a; r=b;}
		inline void build(int a, int b, int c) {l=a; r=b; val=c;}
	}rg[13][N];
	inline bool cmp1(range a, range b) {return a.l<b.l;}
	inline bool cmp2(range a, range b) {return a.r<b.r;}
	void solve() {
		for (int i=1; i<=h; ++i) {
			int lst=-1, beg;
			for (int j=1; j<=w; ++j) if (mp[i][j]) {
				if (lst==-1) lst=j, beg=j;
				else if (j>lst+k-1) {rg[i][++siz[i]].build(beg, lst, (lst-beg)/k+1); beg=lst=j;}
				else lst=j;
			}
			if (lst!=-1) rg[i][++siz[i]].build(beg, lst, (lst-beg)/k+1);
			rg[i][++siz[i]].build(INF, INF, 0);
			for (int j=1; j<=siz[i]+1; ++j) sum[i][j]=sum[i][j-1]+rg[i][j].val;
			// if (i==4) {cout<<"rg: "; for (int j=1; j<=siz[i]; ++j) cout<<rg[i][j].l<<','<<rg[i][j].r<<','<<rg[i][j].val<<' '; cout<<endl;}
			lst=-1;
			for (int j=1; j<=w; ++j) {
				if (mp[i][j]) lst=j;
				pre[i][j]=lst;
			}
			lst=-1;
			for (int j=w; j; --j) {
				if (mp[i][j]) lst=j;
				suf[i][j]=lst;
			}
		}
		for (int i=1,d,l,r; i<=q; ++i) {
			// cout<<"i: "<<i<<endl;
			int ans=0;
			scanf("%d%d%d", &d, &l, &r);
			// cout<<"lr: "<<l<<' '<<r<<endl;
			for (int t=1; t<=d; ++t) {
				// cout<<"t: "<<t<<endl;
				int pos1=lower_bound(rg[t]+1, rg[t]+siz[t]+1, range(l, -1), cmp1)-rg[t];
				int pos2=lower_bound(rg[t]+1, rg[t]+siz[t]+1, range(-1, r), cmp2)-rg[t];
				if ((~suf[t][l]&&~pre[t][r]) && (suf[t][l]<=r&&pre[t][r]>=l)) {
					if (pos1==pos2+1) {
						ans+=(pre[t][r]-suf[t][l])/k+1;
					}
					else {
						if (pos1>1 && rg[t][pos1-1].r>=suf[t][l] && rg[t][pos1-1].r<=pre[t][r]) {
							ans+=(rg[t][pos1-1].r-suf[t][l])/k+1;
							// if (t==9) cout<<"r1: "<<(rg[t][pos1-1].r-l)/k+1<<endl;
						}
						if (rg[t][pos2].l<=pre[t][r]) {
							ans+=(pre[t][r]-rg[t][pos2].l)/k+1;
							// if (t==9) cout<<"r2: "<<(r-rg[t][pos2].l)/k+1<<endl;
						}
						ans+=sum[t][pos2-1]-sum[t][pos1-1];
					}
				}
				// if (t==4) cout<<"pos: "<<pos1<<' '<<pos2<<endl;
				// cout<<"ans: "<<ans<<endl;
				// cout<<"add: "<<sum[t][pos2-1]-sum[t][pos1-1]<<endl;
			}
			printf("%d\n", ans);
		}
		exit(0);
	}
}

namespace task2{
	int pre[13][N], suf[13][N], siz[13], sum[13][N];
	int dp[13][30][N];
	inline int dep(int j) {return w-j+1;}
	void solve() {
		for (int i=1,lst; i<=h; ++i) {
			lst=0;
			for (int j=1; j<=w; ++j) {
				if (mp[i][j]) lst=j;
				pre[i][j]=lst;
			}
			lst=w+1;
			suf[i][w+1]=w+1;
			for (int j=w; j; --j) {
				if (mp[i][j]) lst=j;
				suf[i][j]=lst;
			}
			for (int j=1; j<=w; ++j) {
				dp[i][0][j]=suf[i][j]+k-1;
				cout<<"dp[0]: "<<j<<' '<<dp[i][0][j]<<endl;
			}
			for (int j=w; j; --j) {
				for (int s=1; s<25; ++s)
					if (dep(j)>(1<<s)) {
						if (dp[i][s-1][j]<=w) {
							dp[i][s][j]=suf[i][dp[i][s-1][j]];
							// cout<<"suf: "<<	suf[i][dp[i][s-1][j]] <<endl;
							if (suf[i][dp[i][s-1][j]]<=w) {
								dp[i][s][j]=dp[i][s-1][ suf[i][dp[i][s-1][j]] ];
								cout<<"dp: "<<dp[i][s][j]<<endl;
								cout<<"from: "<<i<<' '<<s<<' '<<j<<endl;
								cout<<"get: "<<i<<' '<<s-1<<' '<<suf[i][dp[i][s-1][j]]<<endl;
							}
						}
						else dp[i][s][j]=w;
					}
					else dp[i][s][j]=w;
			}
		}
		for (int i=1,d,l,r; i<=q; ++i) {
			// cout<<"i: "<<i<<endl;
			int ans=0;
			scanf("%d%d%d", &d, &l, &r);
			// cout<<"lr: "<<l<<' '<<r<<endl;
			for (int t=1; t<=d; ++t) {
				// cout<<"t: "<<t<<endl;
				int now=suf[t][l], ed=pre[t][r];
				cout<<"now: "<<now<<endl;
				for (int j=25; ~j; --j)
					if (now<=ed && dp[t][j][now] && dp[t][j][now]<=ed) {
						ans+=(1<<j);
						now=suf[t][dp[t][j][now]];
						cout<<"jump: "<<now<<' '<<j<<' '<<suf[t][dp[t][j][now]]<<endl;
					}
			}
			printf("%d\n", ans);
		}
		exit(0);
	}
}

namespace task{
	int pre[13][N], suf[13][N], siz[13], sum[13][N];
	int dp[13][18][N], dep[13][N];
	void solve() {
		for (int i=1,lst; i<=h; ++i) {
			lst=0;
			for (int j=1; j<=w; ++j) {
				if (mp[i][j]) lst=j;
				pre[i][j]=lst;
			}
			lst=w+1;
			suf[i][w+1]=w+1;
			for (int j=w; j; --j) {
				if (mp[i][j]) lst=j;
				suf[i][j]=lst;
			}
			for (int j=w; j; --j) {
				if (j+k-1>=w) dep[i][j]=1;
				else if (!mp[i][j]) dep[i][j]=dep[i][suf[i][j]];
				else dep[i][j]=dep[i][suf[i][j+k]]+1;
				// cout<<"dep["<<j<<"]: "<<dep[i][j]<<endl;
			}
			for (int j=1; j<=w; ++j) {
				dp[i][0][j]=min(suf[i][j]+k, w+2);
				// cout<<"dp[0]: "<<j<<' '<<dp[i][0][j]<<endl;
			}
			for (int j=w; j; --j) {
				for (int s=1; s<=17; ++s)
					if (dep[i][j]>=(1<<s)) {
						dp[i][s][j]=dp[i][s-1][ suf[i][dp[i][s-1][j]] ];
					}
					else dp[i][s][j]=w+2;
			}
		}
		for (int i=1,d,l,r; i<=q; ++i) {
			// cout<<"i: "<<i<<endl;
			int ans=0;
			scanf("%d%d%d", &d, &l, &r);
			// cout<<"lr: "<<l<<' '<<r<<endl;
			for (int t=1; t<=d; ++t) {
				// cout<<"t: "<<t<<endl;
				int now=suf[t][l], ed=pre[t][r]+1;
				// cout<<"now: "<<now<<' '<<ed<<endl;
				for (int j=17; ~j; --j) {
					// cout<<"j: "<<j<<' '<<now<<' '<<dp[t][j][now]<<endl;
					if (now<ed && dp[t][j][now]<=ed) {
						ans+=(1<<j);
						// cout<<"jump: "<<now<<' '<<j<<' '<<suf[t][dp[t][j][now]]<<endl;
						now=suf[t][dp[t][j][now]];
					}
				}
				if (now<ed) ++ans;
			}
			printf("%d\n", ans);
		}
		exit(0);
	}
}

signed main()
{
	freopen("blueshit.in", "r", stdin);
	freopen("blueshit.out", "w", stdout);

	scanf("%d%d%d%d", &h, &w, &k, &q);
	for (int i=1; i<=h; ++i) {
		scanf("%s", s+1);
		for (int j=1; j<=w; ++j) mp[i][j]=(s[j]=='X')?1:0;
	}
	// if (w<=1000) force::solve();
	// else task1::solve();
	task::solve();

	return 0;
}
posted @ 2021-10-06 20:03  Administrator-09  阅读(4)  评论(0编辑  收藏  举报