FJUTOJ2790
这个题贼麻烦 要线段树这么多功能 这颗线段树现在已经同时具备了区间加区间开根区间赋值区间求和区间最大区间最小
1 #include<stdio.h> 2 #include<math.h> 3 #include<string.h> 4 #include<algorithm> 5 using namespace std; 6 const int N=1e4+7; 7 8 int n; 9 10 int id[N],prid[N],deep[N],fa[N],Size[N],son[N],top[N],tot; 11 12 inline char getcharc() 13 { 14 static const int BUFSIZE=100001; 15 static char buf[BUFSIZE],*psta=buf,*pend=buf; 16 if(psta==pend) 17 { 18 psta=buf; 19 pend=buf+fread(buf,1,BUFSIZE,stdin); 20 if(psta==pend) 21 return -1; 22 } 23 return *psta++; 24 } 25 26 float SqrtByCarmack( float number ) 27 { 28 int i; 29 float x2, y; 30 const float threehalfs = 1.5F; 31 32 x2 = number * 0.5F; 33 y = number; 34 i = * ( int * ) &y; 35 i = 0x5f375a86 - ( i >> 1 ); 36 y = * ( float * ) &i; 37 y = y * ( threehalfs - ( x2 * y * y ) ); 38 y = y * ( threehalfs - ( x2 * y * y ) ); 39 y = y * ( threehalfs - ( x2 * y * y ) ); 40 return number*y; 41 } 42 inline void nextInt(int &x) {//读取一个整型 43 44 char c; 45 do c=getcharc(); while (c<'0'||c>'9'); 46 x=c-'0'; 47 while ('0'<=(c=getcharc())&&c<='9') x=x*10+c-'0'; 48 } 49 inline void nextInt(long long &x) {//读取一个整型 50 51 char c; 52 do c=getcharc(); while (c<'0'||c>'9'); 53 x=c-'0'; 54 while ('0'<=(c=getcharc())&&c<='9') x=x*10+c-'0'; 55 } 56 struct Segment_tree 57 { 58 struct Node 59 { 60 long long val,Max,lazy,Min,lazyf; 61 int Size,son[2]; 62 void init() 63 { 64 lazy=son[0]=son[1]=Size=val=Max=val=lazyf=0; 65 } 66 } T[N*4]; 67 int cnt,root; 68 69 void init(int l,int r,long long *a) 70 { 71 cnt=0; 72 root=build(l,r,a); 73 } 74 75 inline void update(int pos) 76 { 77 if(T[pos].Size==1)return ; 78 T[pos].val=T[T[pos].son[0]].val+T[T[pos].son[1]].val; 79 T[pos].Max=max(T[T[pos].son[0]].Max,T[T[pos].son[1]].Max); 80 T[pos].Min=min(T[T[pos].son[0]].Min,T[T[pos].son[1]].Min); 81 } 82 83 inline void pushdown(int pos) 84 { 85 int lc=T[pos].son[0],rc=T[pos].son[1]; 86 if(T[pos].lazyf) 87 { 88 if(lc) 89 { 90 T[lc].lazyf=T[pos].lazyf; 91 T[lc].val=T[pos].lazyf*T[lc].Size; 92 T[lc].Max=T[lc].Min=T[pos].lazyf; 93 T[lc].lazy=0; 94 } 95 if(rc) 96 { 97 T[rc].lazyf=T[pos].lazyf; 98 T[rc].val=T[pos].lazyf*T[rc].Size; 99 T[rc].Max=T[rc].Min=T[pos].lazyf; 100 T[rc].lazy=0; 101 } 102 T[pos].lazyf=0; 103 } 104 if(T[pos].lazy) 105 { 106 if(lc) 107 { 108 T[lc].lazy+=T[pos].lazy; 109 T[lc].val+=T[pos].lazy*T[lc].Size; 110 T[lc].Max+=T[pos].lazy; 111 T[lc].Min+=T[pos].lazy; 112 } 113 if(rc) 114 { 115 T[rc].lazy+=T[pos].lazy; 116 T[rc].val+=T[pos].lazy*T[rc].Size; 117 T[rc].Max+=T[pos].lazy; 118 T[rc].Min+=T[pos].lazy; 119 } 120 T[pos].lazy=0; 121 } 122 } 123 124 inline int build(int l,int r,long long *a) 125 { 126 long long pos=++cnt; 127 T[pos].init(); 128 T[pos].Size=r-l+1; 129 if(l==r) 130 { 131 T[pos].val=a[l]; 132 T[pos].Max=a[l]; 133 T[pos].Min=a[l]; 134 return pos; 135 } 136 int mid=(l+r)>>1; 137 T[pos].son[0]=build(l,mid,a); 138 T[pos].son[1]=build(mid+1,r,a); 139 update(pos); 140 return pos; 141 } 142 143 void add(int L,int R,int l,int r,long long v,int pos=1) 144 { 145 if(L==l&&R==r) 146 { 147 T[pos].val+=v*(r-l+1); 148 T[pos].lazy+=v; 149 T[pos].Max+=v; 150 T[pos].Min+=v; 151 return ; 152 } 153 pushdown(pos); 154 int mid=(L+R)>>1; 155 if(r<=mid) 156 add(L,mid,l,r,v,T[pos].son[0]); 157 else if(l>mid) 158 add(mid+1,R,l,r,v,T[pos].son[1]); 159 else 160 { 161 add(L,mid,l,mid,v,T[pos].son[0]); 162 add(mid+1,R,mid+1,r,v,T[pos].son[1]); 163 } 164 update(pos); 165 } 166 167 void cover(int L,int R,int l,int r,long long v,int pos=1) 168 { 169 if(L==l&&R==r) 170 { 171 T[pos].lazyf=v; 172 T[pos].val=T[pos].lazyf*T[pos].Size; 173 T[pos].Max=T[pos].lazyf; 174 T[pos].Min=T[pos].lazyf; 175 T[pos].lazy=0; 176 return ; 177 } 178 pushdown(pos); 179 int mid=(L+R)>>1; 180 if(r<=mid) 181 cover(L,mid,l,r,v,T[pos].son[0]); 182 else if(l>mid) 183 cover(mid+1,R,l,r,v,T[pos].son[1]); 184 else 185 { 186 cover(L,mid,l,mid,v,T[pos].son[0]); 187 cover(mid+1,R,mid+1,r,v,T[pos].son[1]); 188 } 189 update(pos); 190 } 191 192 void qrt(int L,int R,int l,int r,int pos=1) 193 { 194 if(r==R&&l==L&&(int)(SqrtByCarmack(T[pos].Max)+0.0001)==(int)(SqrtByCarmack(T[pos].Min)+0.0001)) 195 { 196 cover(L,R,l,r,SqrtByCarmack(T[pos].Max)+0.0001,pos); 197 return ; 198 } 199 if(r==R&&l==L&&T[pos].Max-T[pos].Min<=1) 200 { 201 add(L,R,l,r,(int)(SqrtByCarmack(T[pos].Max)+0.0001)-T[pos].Max,pos); 202 return ; 203 } 204 pushdown(pos); 205 int mid=(L+R)>>1; 206 if(r==R&&l==L) 207 { 208 qrt(L,mid,l,mid,T[pos].son[0]); 209 qrt(mid+1,R,mid+1,r,T[pos].son[1]); 210 } 211 else if(r<=mid) 212 qrt(L,mid,l,r,T[pos].son[0]); 213 else if(l>mid) 214 qrt(mid+1,R,l,r,T[pos].son[1]); 215 else 216 { 217 qrt(L,mid,l,mid,T[pos].son[0]); 218 qrt(mid+1,R,mid+1,r,T[pos].son[1]); 219 } 220 update(pos); 221 } 222 223 long long query_Sum(int L,int R,int l,int r,int pos=1) 224 { 225 if(L==l&&R==r) 226 { 227 return T[pos].val; 228 } 229 pushdown(pos); 230 int mid=(L+R)>>1; 231 if(r<=mid) 232 return query_Sum(L,mid,l,r,T[pos].son[0]); 233 else if(l>mid) 234 return query_Sum(mid+1,R,l,r,T[pos].son[1]); 235 else 236 return query_Sum(L,mid,l,mid,T[pos].son[0])+query_Sum(mid+1,R,mid+1,r,T[pos].son[1]); 237 } 238 }tree; 239 int first[N],sign; 240 struct node 241 { 242 int to,next; 243 }edge[N*4]; 244 void creat() 245 { 246 memset(first,0,sizeof(first)); 247 sign=1; 248 } 249 void add_edge(int from,int to) 250 { 251 edge[sign].to=to; 252 edge[sign].next=first[from]; 253 first[from]=sign++; 254 } 255 256 void dfs1(int now,int pre,int d) 257 { 258 deep[now]=d,fa[now]=pre,Size[now]=1; 259 for(int i=first[now];i;i=edge[i].next) 260 { 261 int to=edge[i].to;; 262 if(to==pre)continue; 263 dfs1(to,now,d+1); 264 Size[now]+=Size[to]; 265 if(!son[now]||Size[to]>Size[son[now]]) 266 son[now]=to; 267 } 268 } 269 void dfs2(int now,int Top) 270 { 271 top[now]=Top,id[now]=++tot; 272 prid[id[now]]=now; 273 if(!son[now])return ; 274 dfs2(son[now],Top); 275 for(int i=first[now];i;i=edge[i].next) 276 { 277 int to=edge[i].to; 278 if(to!=son[now]&&to!=fa[now]) 279 { 280 dfs2(to,to); 281 } 282 283 } 284 } 285 286 long long tree_query(int x,int y) 287 { 288 int f1=top[x],f2=top[y]; 289 long long ans=0; 290 while(f1!=f2) 291 { 292 if(deep[f1]<deep[f2])swap(f1,f2),swap(x,y); 293 294 ans+=tree.query_Sum(1,n,id[f1],id[x]); 295 x=fa[f1],f1=top[x]; 296 } 297 ans+=(deep[x]>deep[y])?tree.query_Sum(1,n,id[y],id[x]):tree.query_Sum(1,n,id[x],id[y]); 298 return ans; 299 } 300 301 void tree_add(int x,int y,long long v) 302 { 303 int f1=top[x],f2=top[y]; 304 while(f1!=f2) 305 { 306 if(deep[f1]<deep[f2])swap(f1,f2),swap(x,y); 307 tree.add(1,n,id[f1],id[x],v); 308 x=fa[f1],f1=top[x]; 309 } 310 deep[x]>deep[y]?tree.add(1,n,id[y],id[x],v):tree.add(1,n,id[x],id[y],v); 311 } 312 313 void tree_sqrt(int x,int y) 314 { 315 int f1=top[x],f2=top[y]; 316 while(f1!=f2) 317 { 318 if(deep[f1]<deep[f2])swap(f1,f2),swap(x,y); 319 tree.qrt(1,n,id[f1],id[x]); 320 x=fa[f1],f1=top[x]; 321 } 322 deep[x]>deep[y]?tree.qrt(1,n,id[y],id[x]):tree.qrt(1,n,id[x],id[y]); 323 } 324 325 long long a[N]; 326 327 int main() 328 { 329 //freopen("test.txt","r",stdin); 330 //freopen("output1.txt","w",stdout); 331 int q; 332 nextInt(n),nextInt(q); 333 creat(); 334 int x,y; 335 for(int i=1;i<n;i++) 336 { 337 nextInt(x),nextInt(y); 338 add_edge(x,y); 339 add_edge(y,x); 340 } 341 dfs1(1,0,1); 342 dfs2(1,1); 343 for(int i=1;i<=n;i++) 344 nextInt(a[id[i]]); 345 tree.init(1,n,a); 346 long long op,v; 347 while(q--) 348 { 349 nextInt(op); 350 if(op==1) 351 { 352 nextInt(x); 353 nextInt(y); 354 nextInt(v); 355 tree_add(x,y,v); 356 } 357 else if(op==2) 358 { 359 nextInt(x); 360 nextInt(y); 361 tree_sqrt(x,y); 362 } 363 else 364 { 365 nextInt(x); 366 nextInt(y); 367 printf("%lld\n",tree_query(x,y)); 368 } 369 } 370 return 0; 371 }