\(ray\)樂忠於旅遊,這次他來到了\(t\)城。\(t\)城是乙個水上城市,一共有\(n\)個景點,有些景點之間會用一座橋連線。為了方便遊客到達每個景點但又為了節約成本,\(t\)城的任意兩個景點之間有且只有一條路徑。換句話說,\(t\)城中只有\(n−1\)座橋。
\(ray\)發現,有些橋上可以看到美麗的景色,讓人心情愉悅,但有些橋狹窄泥濘,令人煩躁。於是,他給每座橋定義乙個愉悅度\(w\),也就是說,\(ray\)經過這座橋會增加\(w\) 的愉悅度,這或許是正的也可能是負的。有時,\(ray\)看待同一座橋的心情也會發生改變。
現在,\(ray\) 想讓你幫他計算從\(u\)景點到\(v\)景點能獲得的總愉悅度。有時,他還想知道某段路上最美麗的橋所提供的最大愉悅度,或是某段路上最糟糕的一座橋提供的最低愉悅度。
輸入的第一行包含乙個整數\(n\),表示\(t\)城中的景點個數。景點編號為\(0\)~\(n−1\)。
接下來\(n−1\)行,每行三個整數\(u\)、\(v\)和\(w\),表示有一條\(u\)到\(v\),使\(ray\)愉悅度增加\(w\)的橋。
橋的編號為\(1\)~\(n−1\).\(|w|<=1000\).
輸入的第\(n+1\)行包含乙個整數\(m\),表示\(ray\)的運算元目。
接下來有\(m\)行,每行描述了乙個操作,操作有如下五種形式:
\(c\)
\(i\)
\(w\),表示\(ray\)對於經過第\(i\)座橋的愉悅度變成了\(w\)。
\(n\)
\(u\)
\(v\),表示\(ray\)對於經過景點u到v的路徑上的每一座橋的愉悅度都變成原來的相反數。
\(sum\)
\(u\)
\(v\),表示詢問從景點\(u\)到\(v\)所獲得的總愉悅度。
\(max\)
\(u\)
\(v\),表示詢問從景點\(u\)到\(v\)的路徑上的所有橋中某一座橋所提供的最大愉悅度。
\(min\)
\(u\)
\(v\),表示詢問從景點\(u\)到\(v\)的路徑上的所有橋中某一座橋所提供的最小愉悅度。
測試資料保證,任意時刻,\(ray\)對於經過每一座橋的愉悅度的絕對值小於等於\(1000\)。
對於每乙個詢問(操作\(s\)、\(max\) 和\(min\)),輸出答案。
30 1 1
1 2 2
8sum 0 2
max 0 2
n 0 1
sum 0 2
min 0 2
c 1 3
sum 0 2
max 0 232
1-153
樹鏈剖分單點修改,區間修改,區間(最大值,最小值,和)查詢
關鍵在於區間修改,題目讓取反,可以開乙個\(bool\)的\(opp\)(相當與\(lazy\))表示是否需要取反,每次opp^=1;
注意:
1.題目中沒說明\(n\)的範圍,我是開到\(5w\)才\(ac\)的.
2.\(pushdown\)的時候不止修改\(sum\),還有\(max\)和\(min\).
3.將邊權(父親-->兒子)賦給兒子的點權
4.由於點權的特殊性,在修改和查詢中當節點\(x,y\)跳到同一條鏈上時,特判\(x==y\)且查詢[修改]區間為\((dfn[x]+1~dfn[y])\)
#define rg register
#include#includeusing namespace std;
const int n=51000;
inline int read()
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*w;
}int n,m,cnt,ct;
int last[n],size[n],fa[n],dep[n],son[n],val[n],top[n],dfn[n],rk[n];
int sum[n<<2],max[n<<2],min[n<<2];
bool opp[n<<2];
struct edgee[n<<1];
inline void insert(int u,int v,int w)
;last[u]=cnt;
e[++cnt]=(edge);last[v]=cnt;
}void dfs1(int now)
}void dfs2(int now,int top)
}inline void pushup(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);
pushup(root);
}inline void pushdown(int root)
void modify_point(int root,int l,int r,int s,int k)
//注意max,min,sum都要修改
int mid=(l+r)>>1;
if(s<=mid)modify_point(root<<1,l,mid,s,k);
else modify_point(root<<1|1,mid+1,r,s,k);
pushup(root);
}void modify(int root,int l,int r,int ll,int rr)
int mid=(l+r)>>1;
if(ll<=mid)modify(root<<1,l,mid,ll,rr);
if(mid>1,ans;
if(op==1)ans=0;
if(op==2)ans=-1e9;
if(op==3)ans=1e9;
if(ll<=mid)
if(middep[y])swap(x,y);
if(x!=y)modify(1,1,n,dfn[x]+1,dfn[y]);//dfn[x]對應的點權不在修改範圍中
}inline int query_tree(int x,int y,int op)//op=1:查詢和;op=2:查詢最大值;op=3:查詢最小值
int main()
dep[0]=1;
dfs1(0);
dfs2(0,0);
build(1,1,n);
m=read();
rg char act[5];
rg int u,v;
while(m--)
;if(act[0]=='n');
if(act[0]=='s')
if(act[1]=='a')
if(act[1]=='i')
}return 0;
}
國家集訓隊 旅遊
題目背景 ray 樂忠於旅遊,這次他來到了 t 城。t 城是乙個水上城市,一共有 nn 個景點,有些景點之間會用一座橋連線。為了方便遊客到達每個景點但又為了節約成本,t 城的任意兩個景點之間有且只有一條路徑。換句話說,t 城中只有 n 1n 1 座橋。ray 發現,有些橋上可以看到美麗的景色,讓人心...
國家集訓隊 旅遊
link 很簡單一道題,評紫實在是有點暴殄天物。邊權下放到點權然後查詢時注意不要查詢lca的值即可。本來以為在區間取反的基礎上還有個區間加所以雙lazy還有點麻煩時,突然發現它似乎只有單點修改。唯一不好的事就是我把樹剖的板子打錯了。應該判的是top的深度大小,然後我 竟然把這茬給忘了。於是調了兩個小...
luogu P1505 國家集訓隊 旅遊
題面傳送門 第一次一遍過國集紫題。好激動。一看就是樹剖,只不過操作有點多。把每條邊的權值放在兒子節點即可。對於取相反數放懶標記即可。其他是樹剖正常操作。實現 include include define max a,b a b a b define min a,b a b a b using nam...