一道裸的剖分被乙個極度sb的錯誤卡了兩天。。。。。。
題意很明顯,維護5個操作:單點修改,區間取相反數,區間求和,區間求最大值,區間求最小值。
考慮第乙個操作,對於一條路徑,如果修改了他的權值,那麼只會對深度較淺的乙個點向下走、深度較深的向上走會產生影響,所以單點修改較深點權值。(見**update1操作)
考慮第二個操作,就是區間交換最大值最小值、區間和最大值最小值取反即可(見**push_now操作)
考慮第三、四、五個操作,直接在樹剖的時候統計答案即可。
#includeusing namespace std;
const int maxn=1e5+10;
const int maxm=1e6+10;
const int inf=0x3f3f3f3f;
int n,m,cnt=1,tot;
int head[maxn],fa[maxn],top[maxn],depth[maxn],siz[maxn],son[maxn];
int a[maxn],dfn[maxn],ys[maxn];
struct edgeedge[maxm];
struct nodetr[maxn<<2];
void push_up(int root)
void push_now(int root)
void push_down(int root)
}void build(int root,int l,int r)
int mid=l+r>>1;
build(root<<1,l,mid);
build(root<<1|1,mid+1,r);
push_up(root);
}void update1(int root,int l,int r,int x,int key)
push_down(root);
int mid=l+r>>1;
if(x<=mid)
update1(root<<1,l,mid,x,key);
else
update1(root<<1|1,mid+1,r,x,key);
push_up(root);
}void update2(int root,int l,int r,int l,int r)
push_up(root);
}int query_sum(int root,int l,int r,int l,int r)
}int query_max(int root,int l,int r,int l,int r)
}int query_min(int root,int l,int r,int l,int r)
}void add(int x,int y,int z)
inline void dfs1(int p)
}inline void dfs2(int p,int tp)
}void change(int x,int y)
int read()
int main()
dfs1(1);
dfs2(1,1);
build(1,1,n);
m=read();
while(m--)
return 0;
}
P1505 國家集訓隊 旅遊 樹鏈剖分
題目描述 ray 樂忠於旅遊,這次他來到了t 城。t 城是乙個水上城市,一共有 n 個景點,有些景點之間會用一座橋連線。為了方便遊客到達每個景點但又為了節約成本,t 城的任意兩個景點之間有且只有一條路徑。換句話說,t 城中只有n 1 座橋。ray 發現,有些橋上可以看到美麗的景色,讓人心情愉悅,但有...
P1505 國家集訓隊 旅遊 (樹鏈剖分)
傳送門 很明顯是樹鏈剖分,因為是邊權,所以將每個邊權給深度大的那個點可以了,根節點不用賦值,要求最大值和最小值,所以線段樹不包含根節點。因為點是從0編號的,所以父節點和重兒子陣列要初始化。include include include using namespace std const int n ...
樹鏈剖分 p1505 國家集訓隊 旅遊
ray 樂忠於旅遊,這次他來到了t 城。t 城是乙個水上城市,一共有 n 個景點,有些景點之間會用一座橋連線。為了方便遊客到達每個景點但又為了節約成本,t 城的任意兩個景點之間有且只有一條路徑。換句話說,t 城中只有n 1 座橋。ray 發現,有些橋上可以看到美麗的景色,讓人心情愉悅,但有些橋狹窄泥...