qzezoj 1574 Chewbacca
题面传送门
这道题似乎是板子,就是裸的\(LCA\),然后我就打了个暴力\(LCA\)过掉了。
思路:先把两个点提到同一层,然后一起向上提,直到提到同一个节点停止,计算答案。
因为是满二叉树,所以时间复杂度\(O(klog^mn)\)
代码实现:
#include<cstdio>
#define abs(x) ((x)>0?(x):-(x))
using namespace std;
long long n,m,k,tot,pus,ans,x,y,now,fs,f;
inline void swap(long long &x,long long &y){x^=y,y^=x,x^=y;}
inline void read(long long &x){
char s=getchar();x=0;
while(s<'0'||s>'9') s=getchar();
while(s>='0'&&s<='9') x=(x<<3)+(x<<1)+(s^48),s=getchar();
}
int main(){
register int i,j;
scanf("%lld%lld%lld",&n,&m,&k);
for(i=1;i<=k;i++){
read(x);read(y);
//printf("%lld %lld\n",x,y);
if(x>y) swap(x,y);
if(k==1){printf("%lld\n",y-x);continue;}
tot=x;
pus=0;
while(tot!=1) pus++,tot=(tot-2)/m+1;
pus++;
ans=1;now=1;
for(j=1;j<=pus;j++) ans+=now,now*=m;
ans--;
//printf("%lld\n",pus);
fs=f=0;
while(y>ans) y=(y-2)/m+1,f++;
while(x!=y) y=(y-2)/m+1,x=(x-2)/m+1,f+=2;
printf("%lld\n",f);
}
}
似乎可以用倍增做到\(O(mlog^klog^2n)\),还不用担心被卡,但我打不来\(qwq\)。