1. 程式人生 > 實用技巧 >Yoi #423. 挖掘機

Yoi #423. 挖掘機

題面


分析

​ 法1:分治,類似分治揹包,程式碼複雜度極高

​ 法2:倍增,預處理出跳2^k^次步後的落點,再開陣列處理邊界

#include<bits/stdc++.h>
using namespace std;

const int N=1e5+5;
int h,n,K,Q,f[13][N][18],ans,g[13][N];
char s[N];

int main() {
	freopen("bueshit.in","r",stdin);
	freopen("bueshit.out","w",stdout);
	scanf("%d%d%d%d",&h,&n,&K,&Q);
	for(int i=1;i<=h;i++) {
		scanf("%s",s+1); int lst=n+1;
		for(int j=n;j>=1;j--) {
			if(s[j]=='X') lst=j;
			g[i][j]=lst;
			f[i][j][0]=min(lst+K,n+1);
		}
		f[i][n+1][0]=n+1;
		for(int k=1;k<=16;k++) {
			for(int j=1;j<=n+1;j++) {
				f[i][j][k]=f[i][f[i][j][k-1]][k-1];
			}
		}
	}
	while(Q--) {
		int D,l,r; scanf("%d%d%d",&D,&l,&r);
		ans=0;
		for(int i=1;i<=D;i++) {
			int u=l;
			for(int k=16;k>=0;k--) {
				if(f[i][u][k]<=r) {
					u=f[i][u][k],ans+=(1<<k);
				}
			}
			if(g[i][u]<=r) ans++;
		}
		printf("%d\n",ans);
	}
	return 0;
}