首先贪心的思路很好想
然后发现如果有 \(>k\) 的空缺,贪心的部分会断掉
所以可以分成几块,二分出询问的区间包含了哪些段
但是只包含了一部分的不好处理
于是换个思路,考虑倍增优化贪心覆盖
考场上因为倍增的时候跳出边界了没跳出来炸掉了考完拿拍造了几百组数据面向数据调试过了
#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;
}