1 solutions

  • 0
    @ 2023-9-15 10:40:35

    这道题一看似乎不是树剖

    但是我们可以把问题转化一下:把每次操作变成把从 llrr 的所有点到根的路径边权都加上1,然后答案就是从 zz 到根的边权和。

    然后我们就可以转成离线操作了。

    每次操作先在 l1l-1 打上减标记,在 rr 打上加标记,然后从 11nn 依次枚举,每次扫到一个减标记就将这个询问的答案减掉,每次扫到一个加标记就将这个询问的答案加上。

    就能做到 O(nlogn)O(nlog n) 了。

    int main(){
    	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); 
    	cin>>n>>m;
    	for(int i=1;i<n;i++)cin>>x,ve[x+1].emplace_back(i+1),ve[i+1].emplace_back(x+1);
    	dfs1(1,-1,1);
    	dfs2(1,1);
    	build(1,1,n);
    	for(int i=1;i<=m;i++){
    		cin>>l>>r>>z;z++;
    		a[r+1].emplace_back(i);
    		b[l].emplace_back(i);
    		ak[i]=z;
    	}
    	for(int i=1;i<=n;i++){
    		change_path(1,i,1);
    		for(int v:a[i]){
    			ans[v]+=query_path(1,ak[v]),ans[v]%=mod;
    		} 
    		for(int v:b[i]){
    			ans[v]-=query_path(1,ak[v]),ans[v]%=mod;
    		}
    	}
    	for(int i=1;i<=m;i++)cout<<(ans[i]+mod)%mod<<"\n";
    	return 0;
    }
    
    • 1

    Information

    ID
    3152
    Time
    1000ms
    Memory
    125MiB
    Difficulty
    6
    Tags
    # Submissions
    5
    Accepted
    2
    Uploaded By