想不到倍增.
已经肯定处理每一行的复杂度都是在 \(O(1)\) ~ \(O(logn)\) 的复杂度了.
也知道应该是处理每个起点之后的东西.
可偏偏不知道应该用什么算法来解决.
哪怕把倍增告诉我也不知道如何处理,太菜...
这个题把没有用的删去之后,确实就是很显然的倍增了.
#include<bits/stdc++.h> using namespace std; namespace BSS { #define ll int #define ull unsigned ll #define lf double #define lbt(x) (x&(-x)) #define mp(x,y) make_pair(x,y) #define lb lower_bound #define ub upper_bound #define Fill(x,y) memset(x,y,sizeof x) #define Copy(x,y) memcpy(x,y,sizeof x) #define File(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout) inline ll read() { ll res=0; bool cit=1; char ch; while(!isdigit(ch=getchar())) if(ch=='-') cit=0; while(isdigit(ch)) res=(res<<3)+(res<<1)+(ch^48),ch=getchar(); return cit?res:-res; } } using namespace BSS; const ll N=1e5+21; ll m,n,t,ops,lg2; ll c[15][N],f[15][N],g[15][N][21]; signed main(){ File(blueshit); n=read(),m=read(),t=read(),ops=read(),lg2=log2(m)+1; char s[N]; Fill(f,0x3f),Fill(g,0x3f); for(int i=1;i<=n;i++){ scanf("%s",s+1); for(int j=1;j<=m;j++) c[i][j]=(s[j]=='X'); for(int j=m;j>=1;j--){ c[i][j] ? f[i][j]=j : f[i][j]=f[i][j+1]; if(c[i][j]) g[i][j][0]=f[i][j+t]; else if(f[i][j]<=m) g[i][j][0]=g[i][f[i][j]][0]; for(int k=1;k<=lg2;k++){ if(g[i][j][k-1]<=m) g[i][j][k]=g[i][g[i][j][k-1]][k-1]; else break; } } } ll d,l,r,res,now; while(ops--){ d=read(),l=read(),r=read(),res=0; for(int i=1,now=l;i<=d;i++,now=l){ if(f[i][l]>r) continue; for(int j=lg2;j>=0;j--){ if(g[i][now][j]<=r) res+=(1ll<<j),now=g[i][now][j]; } res++; } printf("%d\n",res); } puts(""); exit(0); }