用树剖的全re,吸了氧全ac,有无好心大佬解释一下为何如此?
#include <stdio.h>
#include <iomanip>
#include <vector>
#include <stdlib.h>
#include <cmath>
#include <algorithm>
#include <map>
#include <time.h>
#include <queue>
#include <iostream>
#include <cstring>
#include <set>
using namespace std;
const int maxv=1e5+10;
const int mod=1e9+7;
const int maxNum=0x7fffffff-10;
const double eps=1e-8;
const double PI=3.1415926535;
typedef long long LL;
inline LL read(){
LL x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
x%=mod;
ch=getchar();
}
return x*f;
}
inline void write(int x)
{
if(!x) putchar('0');
char F[200];
int tmp=x>0?x:-x ;
if(x<0)putchar('-') ;
int cnt=0 ;
while(tmp>0)
{
F[cnt++]=tmp%10+'0';
tmp/=10;
}
while(cnt>0)putchar(F[--cnt]) ;
putchar('\n');
}
#define int long long
int n,m,r,p;
const int N =maxv;
struct E{ int v ;int nxt ; } ;
E edge[N << 1] ;
int a[N],fa[N],w[N],id[N],son[N] ;
int cnt,head[N],Add[N<<2],laz[N<<2],dep[N],siz[N],t[N] ;
inline void Add_Edge( int u , int v) { edge[++ cnt].v = v ; edge[cnt].nxt = head[u] ; head[u] = cnt ; return ; }//建边。
#define l(x) x << 1
#define r(x) x << 1 | 1
inline void Push_down( int x , int len) {
laz[l(x)] += laz[x] ; laz[r(x)] += laz[x] ;
Add[l(x)] += laz[x] * (len - (len >> 1)) ; Add[r(x)] += laz[x] * (len >> 1) ;
Add[l(x)] %= p ; Add[r(x)] %= p ;
laz[x] = 0 ; return ;
}
inline void Build( int l , int r , int rt) {//建树
if(l == r) { Add[rt] = a[l] ; return ; }
int mid = l + r >> 1 ;
Build(l , mid , l(rt)) ; Build(mid + 1 , r , r(rt)) ;
Add[rt] = (Add[l(rt)] + Add[r(rt)]) % p ;
}
inline void Update( int a , int b , int l , int r , int rt , int k) {//正常的线段树操作
if(a <= l and r <= b) { laz[rt] += k ; Add[rt] += k * (r - l + 1) ; }
else {
if(laz[rt]) Push_down(rt , r - l + 1) ;
int mid = l + r >> 1 ;
if(a <= mid) Update(a , b , l , mid , l(rt) , k) ;
if(b > mid) Update(a , b , mid + 1 , r , r(rt) , k) ;
Add[rt] = (Add[l(rt)] + Add[r(rt)]) % p ;
}
}
int res = 0 ;
inline void query( int a , int b , int l , int r , int rt) {
if(a <= l and r <= b) { res = (res + Add[rt]) % p ; return ; }
else {
if(laz[rt]) Push_down(rt , r - l + 1) ;
int mid = l + r >> 1 ;
if(a <= mid) query(a , b , l , mid , l(rt)) ;
if(b > mid) query(a , b , mid + 1 , r , r(rt)) ;
}
}
inline int Query( int a , int b , int l , int r , int rt) {//正常的线段树操作
res = 0 ; query(a , b , l , r , rt) ;
return res % p ;
}
inline void Upd_Range( int x , int y , int k) {//链上修改
while(t[x] != t[y]) {
if(dep[t[x]] < dep[t[y]]) swap(x , y) ;
Update(id[t[x]] , id[x] , 1 , n , 1 , k) ;
x = fa[t[x]] ;
}
if(dep[x] > dep[y]) swap(x , y) ;
Update(id[x] , id[y] , 1 , n , 1 , k) ;
}
inline int Query_Range( int x , int y) {//链上查询
int ans = 0 ;
while(t[x] != t[y]) {
if(dep[t[x]] < dep[t[y]]) swap(x , y) ;
ans += Query(id[t[x]] , id[x] , 1 , n , 1) ;
x = fa[t[x]] ;
}
if(dep[x] > dep[y]) swap(x , y) ;
ans += Query(id[x] , id[y] , 1 , n , 1) ;
return ans % p ;
}
inline int Qson( int x) { return Query(id[x] , id[x] + siz[x] - 1 , 1 , n , 1) ; } // 子树查询。
inline void Updson( int x , int k) { Update(id[x] , id[x] + siz[x] - 1 , 1 , n , 1 , k) ; return ; }
inline void Dfs1( int x , int f , int deep) {
dep[x] = deep ; fa[x] = f ; siz[x] = 1 ;
int max_son = -1 ;
for( int i = head[x] ; i ; i = edge[i].nxt) {
int v = edge[i].v ;
if(v == f) continue ;
Dfs1(v , x , deep + 1) ;siz[x] += siz[v] ;
if(siz[v] > max_son) max_son = siz[v] , son[x] = v ;
}
}
int tot = 0 ;
inline void Dfs2( int x , int tf) {
id[x] = ++ tot ; a[tot] = w[x] ; t[x] = tf ; // a 数组重新赋值
if(! son[x]) return ;
Dfs2(son[x] , tf) ;
for( int i = head[x] ; i ; i = edge[i].nxt) {
int v = edge[i].v ;
if(v == fa[x] or v == son[x]) continue ;
Dfs2(v , v) ;
}
}
signed main() {
n = read() ; m = read() ; r = 1; p = 2e9 ;
for(int i = 1 ; i <= n ; i ++) w[i] = 0;
for(int i = 1 ; i <= n - 1 ; i ++) {
int u = read() , v = read() ;
Add_Edge(u , v) ;
Add_Edge(v , u) ;
}
Dfs1(r , 0 , 1) ; Dfs2(r , r) ; Build(1 , n , 1) ;
while(m--){
int a,b,c,d;
scanf("%d%d%d%d",&a,&b,&c,&d);
Upd_Range(a , b , 1) ;
if(Query_Range(c , d)>0) printf("Y\n");
else printf("N\n");
Upd_Range(a , b , -1) ;
}
return 0 ;
}