关于如何解决卡常的问题

P3241 [HNOI2015] 开店

```cpp #include<bits/stdc++.h> typedef long long LL; typedef long double LD; using namespace std; const LL N=200010,M=2000010,INF=0x3f3f3f3f; inline LL max(LL x,LL y){return x>y?x:y;} inline LL min(LL x,LL y){return x<y?x:y;} inline void swap(LL &x,LL &y){x^=y^=x^=y;} LL head[N],ver[M],edge[M],Next[M],tot; LL n,m,t,rt,lastans,d[N],f[N],val[N],vis[N],dist[N],size[N]; LL in[N],out[N],st[N<<2][20],lg[N<<2],ts; struct node{LL pos,sum;}; bool operator <(node a,node b){ return a.pos<b.pos; } vector<node> v[N]; vector<LL> h[N]; void upd(LL u,LL pos,LL dis){ v[u].push_back((node){pos,dis}); } LL ask(LL u,LL l,LL r,LL &fi,LL &se){ fi=lower_bound(v[u].begin(),v[u].end(),(node){l,0})-v[u].begin(); se=upper_bound(v[u].begin(),v[u].end(),(node){r,0})-v[u].begin(); return v[u][fi].sum-v[u][se].sum; } void add(LL x,LL y,LL z){ ver[++tot]=y,edge[tot]=z,Next[tot]=head[x],head[x]=tot; } void dfs(LL x,LL fa){ d[x]=d[fa]+1; in[x]=++ts,st[ts][0]=x; for(LL i=head[x];i;i=Next[i]){ LL y=ver[i],z=edge[i]; if(y==fa)continue; dist[y]=dist[x]+z; dfs(y,x); } out[x]=++ts; if(fa)st[ts][0]=fa; } void init(){ for(LL i=2;i<=N<<1;i++)lg[i]=lg[i>>1]+1; for(LL j=1;(1<<j)<=ts;j++) for(LL i=1;i+(1<<j)-1<=ts;i++){ LL x=st[i][j-1],y=st[i+(1<<(j-1))][j-1]; st[i][j]=(d[x]<d[y])?x:y; } } LL lca(LL x,LL y){ LL l=in[x],r=in[y]; if(l>r)swap(l,r);LL Lg=lg[r-l+1]; return d[st[l][Lg]]<d[st[r-(1<<Lg)+1][Lg]]?st[l][Lg]:st[r-(1<<Lg)+1][Lg]; } LL get(LL x,LL y){ return dist[x]+dist[y]-2*dist[lca(x,y)]; } void get_size(LL x,LL fa){ size[x]=1; for(LL i=head[x];i;i=Next[i]){ LL y=ver[i]; if(y==fa||vis[y])continue; get_size(y,x); size[x]+=size[y]; } } void get_rt(LL x,LL fa,LL sum){ size[x]=1; LL flag=1; for(LL i=head[x];i;i=Next[i]){ LL y=ver[i]; if(y==fa||vis[y])continue; get_rt(y,x,sum); size[x]+=size[y]; if(size[y]>sum/2)flag=0; } if(flag&&sum-size[x]<=sum/2)rt=x; } void get_dis(LL x,LL fa,LL dis){ upd(rt,val[x],dis); for(LL i=head[x];i;i=Next[i]){ LL y=ver[i],z=edge[i]; if(y==fa||vis[y])continue; get_dis(y,x,dis+z); } } void solve(LL x){ vis[x]=1; for(LL i=head[x];i;i=Next[i]){ LL y=ver[i],z=edge[i]; if(vis[y])continue; get_size(y,x); get_rt(y,x,size[y]); f[rt]=x; h[x].push_back(rt); get_dis(y,x,z); solve(rt); } upd(x,INF,0); sort(v[x].begin(),v[x].end()); for(LL i=v[x].size();i;i--) v[x][i-1].sum+=v[x][i].sum; } int main(){ scanf("%lld%lld%lld",&n,&m,&t); for(LL i=1;i<=n;i++) scanf("%lld",&val[i]); for(LL i=1;i<n;i++){ LL x,y,z; scanf("%lld%lld%lld",&x,&y,&z); add(x,y,z),add(y,x,z); } dfs(1,0); init(); get_rt(1,0,n); solve(rt); while(m--){ LL x,a,b,l,r,fi,se; scanf("%lld%lld%lld",&x,&a,&b); l=(a+lastans)%t; r=(b+lastans)%t; if(l>r)swap(l,r); lastans=0; for(LL i=0;i<(LL)h[x].size();i++) lastans+=ask(h[x][i],l,r,fi,se); for(LL i=x;f[i];i=f[i]){ LL len=get(x,f[i]); for(LL j=0;j<(LL)h[f[i]].size();j++) if(h[f[i]][j]!=i)lastans+=ask(h[f[i]][j],l,r,fi,se),lastans+=len*(se-fi); if(l<=val[f[i]]&&val[f[i]]<=r)lastans+=len; } printf("%lld\n",lastans); } return 0; } ```
by Diaоsi @ 2021-08-15 15:55:21


@[十里](/user/526711) @[ATZdhjeb](/user/483317) @[zyc2003](/user/144810)
by Diaоsi @ 2021-08-15 15:55:53


$\%\%\%$
by 滑不拉稽 @ 2021-08-15 16:11:26


|