This commit is contained in:
ljcjames 2022-08-11 21:46:01 +08:00
commit adb365022c
31 changed files with 860 additions and 0 deletions

7
.gitattributes vendored Normal file
View File

@ -0,0 +1,7 @@
*.xlsx filter=lfs diff=lfs merge=lfs -text
*.pdf filter=lfs diff=lfs merge=lfs -text
*.pptx filter=lfs diff=lfs merge=lfs -text
*.ppt filter=lfs diff=lfs merge=lfs -text
*.doc filter=lfs diff=lfs merge=lfs -text
*.docx filter=lfs diff=lfs merge=lfs -text
*.xls filter=lfs diff=lfs merge=lfs -text

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
*.exe
Thumbs.db
~$*

View File

@ -0,0 +1,5 @@
[{000214A0-0000-0000-C000-000000000046}]
Prop3=19,11
[InternetShortcut]
IDList=
URL=https://vjudge.net/contest/507272

BIN
8.1/最大流20220522.pptx (Stored with Git LFS) Normal file

Binary file not shown.

BIN
8.1/最小费用最大流20220801.pptx (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

119
8.10/A - 门.cpp Normal file
View File

@ -0,0 +1,119 @@
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
const double inf=1e100,EPS=1e-6;
const int W=20;
double l,now;
int n;
struct wall
{
double x,y[6],val[5];
} w[W];
//big bug:double->int
double length(double x1,double y1,double x2,double y2)
{
double x=x1-x2,y=y1-y2;
return sqrt(x*x+y*y);
}
double cross(double x1,double y1,double x2,double y2)
{
return x1*y2-x2*y1;
}
double same(double x0,double y0,double x3,double y3,double x1,double y1,double x2,double y2)
{
double x=x3-x0,y=y3-y0;//y0->x0
return cross(x,y,x1-x0,y1-y0)*cross(x,y,x2-x0,y2-y0);
}
//WA double 判断正负要用
int sign(double d)
{
if(fabs(d)<EPS)
{
return 0;
}
else return d>0? 1:-1;
}
bool ob(int li,int lj,int ri,int rj)
{
for(int i=li+1; i<ri; i++)
{
for(int j=0; j<=4; j+=2)
{
// printf("(%.0lf,%.0lf)(%.0lf,%.0lf)/(%.0lf,%.0lf)(%.0lf,%.0lf):",w[i].x,w[i].y[j],w[i].x,w[i].y[j+1],w[li].x,w[li].y[lj],w[ri].x,w[ri].y[rj]);
// printf("[%.2lf/%.2lf]\n",same(w[i].x,w[i].y[j],w[i].x,w[i].y[j+1],w[li].x,w[li].y[lj],w[ri].x,w[ri].y[rj]),same(w[li].x,w[li].y[lj],w[ri].x,w[ri].y[rj],w[i].x,w[i].y[j],w[i].x,w[i].y[j+1]));
//两个都同方向才是,应该&&,错以为|| ,不是0都是真 两个小于0才是香蕉
if(sign(same(w[i].x,w[i].y[j],w[i].x,w[i].y[j+1],w[li].x,w[li].y[lj],w[ri].x,w[ri].y[rj]))<0&&sign(same(w[li].x,w[li].y[lj],w[ri].x,w[ri].y[rj],w[i].x,w[i].y[j],w[i].x,w[i].y[j+1]))<0)
{
return 0;
}
}
}
return 1;
}
void find(int ii,int jj)
{
for(int i=0; i<ii; i++)
{
for(int j=1; j<=4; j++)
{
l=length(w[ii].x,w[ii].y[jj],w[i].x,w[i].y[j]);
now=w[i].val[j]+l;//i j ii,jj搞反了
if(now<w[ii].val[jj]&&ob(i,j,ii,jj))
{
w[ii].val[jj]=now;
}
// printf("(%.0lf,%.0lf)(%.0lf,%.0lf):length:%.3lf,now:%.3lfval:%.3lf\n",w[ii].x,w[ii].y[jj],w[i].x,w[i].y[j],l,now,w[ii].val[jj]);
if(i==0) break;
}
}
}
void doit()
{
for(int i=1; i<=n; i++)
{
for(int j=1; j<=4; j++)
{
find(i,j);
if(i==n) break;
}
}
}
int main()
{
while(1)
{
scanf("%d",&n);
if(n==-1) return 0;
memset(&w,0,sizeof(wall)*(n+1));
w[0].x=0;
w[0].y[1]=5;
w[0].val[1]=0;
for(int i=1; i<=n; i++)
{
w[i].y[0]=0;
w[i].y[5]=10;
for(int j=1; j<=4; j++)//又打成i
{
w[i].val[j]=inf;
}
}
for(int i=1; i<=n; i++)
{
scanf("%lf",&w[i].x);
// cin>>w[i].x;
for(int j=1; j<=4; j++)// 又是j
{
scanf("%lf",&w[i].y[j]);
// cin>>w[i].y[j];
}
}
w[++n].x=10;
w[n].y[1]=5;
w[n].val[1]=inf;// bug 没赋值
doit();
printf("%.2lf\n",w[n].val[1]);
}
}

70
8.10/B - 玩具.cpp Normal file
View File

@ -0,0 +1,70 @@
//https://vjudge.net/contest/508277#problem/B
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
const double inf=1e100,EPS=1e-6;
const int N=5e3+1;
double l,now;
int n,m;
struct edge
{
int x[3],y[3],w;//int->double
} a[N];
#define xy x1,y1
#define double int
double cross(double x1,double y1,double x2,double y2)
{
// printf("(%d,%d)(%d,%d):%d\n",x1,y1,x2,y2,x1*y2-x2*y1) ;
return x1*y2-x2*y1;
}
//l,r没算好
void find(int l,int r,int mid,int x1,int y1)
{
// printf("l:%d,r:%d,mid:%d(%d,%d),x1:%d,y1:%d\n",l,r,mid,a[mid].x[0],a[0].y[0],x1,y1);
if(l==r)
{
a[l].w++;
return ;//二分结束没有return
}
if(cross(a[mid].x[0],a[0].y[0],x1-a[mid].x[1],y1-a[0].y[1])<=0)//顺时针是-,逆时针是+
{
find(l,mid-1,(l+mid)/2,xy);
}
else
{
find(mid,r,(mid+r+1)/2,xy);
}
}
int main()
{
while(1)
{
scanf("%d",&n);
if(n==0) return 0;
int x1,y1;
memset(a,0,sizeof(edge)*(n+1));
scanf("%d%d%d%d%d",&m,&a[0].x[1],&a[0].y[1],&a[0].x[2],&a[0].y[2]);
a[0].x[2]=a[0].x[1];
a[0].x[0]=a[0].x[2]-a[0].x[1];
a[0].y[0]=a[0].y[2]-a[0].y[1];
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a[i].x[1],&a[i].x[2]);
a[i].x[0]=a[i].x[2]-a[i].x[1];
// cout<<a[i].x[0]<<"\\";
}
for(int i=1;i<=m;i++)
{
scanf("%d%d",&x1,&y1);
find(0,n,(n+1)/2,xy);
}
for(int i=0;i<=n;i++)
{
printf("%d: %d\n",i,a[i].w);//Presentation Error
}
printf("\n"); //Presentation Error
}
}

View File

@ -0,0 +1,157 @@
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=3e4+1,N2=N<<1,inf=0x3f3f3f3f;//N2 双向边记得*2
int to[N2],h[N2],ne[N2];
int nid[N],oid[N],top[N],w[N],dep[N],fa[N];
int siz[N],son[N];//子树节点数重边儿子siz最大的儿子
int a[N<<2];
int t,u,v,w1,qu,n,m,cnt=0;
char opt;
#define ls rt<<1
#define rs rt<<1|1
#define mid ((l+r)>>1) //>>1写成>>2
#define lson ls,l,mid //l写成1
#define rson rs,mid+1,r
#define len (r-l+1)
void add(int u,int v)
{
to[++cnt]=v;
ne[cnt]=h[u];
h[u]=cnt;
}
//以下是线段树
int tot=0;
void build(int rt,int l,int r)
{
if(l==r)
{
a[rt]=w[oid[l]];
// printf("l:%d,qm[%d]=w[%d]=%d\n",l,rt,oid[l],qm[rt]);
return;
}
// if(rt<=mid)
build(ls,l,mid);
// else
build(rs,mid+1,r);
// printf("a[%d]=a[%d]%d/a[%d]%d\n",rt,ls,qm[ls],rs,qm[rs]);
}
inline void pushdown(int rt)
{
a[ls]+=a[rt];
a[rs]+=a[rt];
a[rt]=0;
}
inline int q(int rt,int l,int r,int u)
{
if(l==r)
{
// printf("[%d]",rt);
return a[rt];
}
pushdown(rt);
int res=0;
if(u<=mid)res=q(lson,u);
if(u>mid)res=q(rson,u);
return res;
}
//以上是线段树
inline void dfs1(int u,int f,int deep)
{
fa[u]=f;
dep[u]=deep;
siz[u]=1;
for(int i=h[u]; i; i=ne[i])
{
int v=to[i];//bug int
if(v==f) continue;//bug 放后了
// printf("(wo[%d]=val[%d]=%d)\n",v,i,val[i]);
dfs1(v,u,deep+1);
siz[u]+=siz[v];
if(son[u]==0||siz[v]>siz[son[u]])
{
son[u]=v;
}
}
// printf("out:%d:fa:%d,dep:%d,siz:%d\n",u,f,deep,siz[u]);
}
inline void dfs2(int u,int tp)
{
nid[u]=++cnt;
oid[cnt]=u;
top[u]=tp;
// printf("%d:nid:%d,nw:%d,top:%d\n",u,cnt,wo[u],topf);
if(!son[u]) return;
dfs2(son[u],tp);
for(int i=h[u]; i; i=ne[i])
{
v=to[i];
if(v!=fa[u]&&v!=son[u])
{
dfs2(v,v);
}
}
}
inline void change(int L,int R,int w1,int rt,int l,int r)
{
if(L<=l&&r<=R)
{
a[rt]+=w1;
// printf("u:%d,a[%d]=%d(l=r=%d)\n",u,rt,w1,l);
}
else
{
if(u<=mid)
{
change(L,R,w1,lson);
}
else change(L,R,w1,rson);
// printf("u:%d,a[%d]=a[%d]%d/a[%d]%d\n",u,rt,ls,a[ls],rs,a[rs]);
}
}
int main()
{
scanf("%d%d%d",&n,&m,&qu);
cnt=0;
for(int i=1; i<=n; i++)
{
scanf("%d",&w[i]);
}
for(int i=1; i<=m; i++)
{
scanf("%d%d",&u,&v);// 多打一个%d c0000005 APPCRASH
// printf("(%d)",i);
add(u,v);
add(v,u);
}
dfs1(1,0,1);
cnt=0;
dfs2(1,1);
build(1,1,cnt);
printf("(%d)",qu);
while(qu--)
{
scanf("%c",&opt);//"&"
if(opt=='I')
{
scanf("%d%d%d",&u,&v,&w1);//%d,加了变量没加%d
change(nid[u],nid[v],w1,1,1,cnt);
}
else if(opt=='D')
{
scanf("%d%d%d",&u,&v,&w1);
change(nid[u],nid[v],w1*-1,1,1,cnt);
}
else
{
scanf("%d",&u);
printf("%d\n",q(1,1,n,u));
}
}
return 0;
}

105
8.10/E - Intersection.cpp Normal file
View File

@ -0,0 +1,105 @@
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
const double inf=1e100,EPS=1e-6;
const int N=5;
double cr0,cr1;
int n,s,j,bx[2],by[2],init;
struct xy
{
int x,y;
} v[N],d[N],e[2];
//WA double 判断正负要用
int sign(double d)
{
if(fabs(d)<EPS)
{
return 0;
}
else return d>0? 1:-1;
}
double cross(double x1,double y1,double x2,double y2)
{
return x1*y2-x2*y1;
}
int same(double x0,double y0,double x3,double y3,double x1,double y1,double x2,double y2)
{
double x=x3-x0,y=y3-y0;//y0->x0
int a=sign(cross(x,y,x1-x0,y1-y0)),b=sign(cross(x,y,x2-x0,y2-y0));
//WA*N 两条线段是在同一直线上的但是没有重合部分,那么通过跨立实验返回的是相交,就错了,必须再加上快速排斥
if(a==0&&b==0)
{
if(max(x0,x3)<min(x1,x2)||min(x0,x3)>max(x1,x2)||max(y0,y3)<min(y1,y2)||min(y0,y3)>max(y1,y2))
{
return 1;
}
}
if(a<0&&b<0)
{
return 2;
}
return a*b;
}
int main()
{
scanf("%d",&n);
while(n--)
{
for(int i=0; i<2; i++)
{
scanf("%d%d",&e[i].x,&e[i].y);//&又忘了
}
for(int i=0; i<2; i++)
{
scanf("%d%d",&bx[i],&by[i]);
}
for(int i=1; i<N; i++)
{
if(i<3)d[i].x=min(bx[0],bx[1]);
else d[i].x=max(bx[0],bx[1]);
if(i%3==1) d[i].y=min(by[0],by[1]);
else d[i].y=max(by[0],by[1]);
}
init=0;
for(int i=1; i<N; i++)
{
j=i%4+1;//j搞反了
//两个都同方向才是,应该&&,错以为|| ,不是0都是真 两个小于0才是香蕉
s=same(d[i].x,d[i].y,d[j].x,d[j].y,e[0].x,e[0].y,e[1].x,e[1].y);
if(s==2)
{
init++;
}
if(s<=0)
{
if(same(e[0].x,e[0].y,e[1].x,e[1].y,d[i].x,d[i].y,d[j].x,d[j].y)<=0)
{
init=4;
break;
}
}
// printf("(%d,%d)",d[i].x,d[i].y);
}
if(init==4)
{
printf("T\n");
}
else
{
printf("F\n");
}
}
return 0;
//v[i].x=d[j].x-d[i].x;
//v[i].y=d[j].y-d[i].y;
//cr0=cross(v[i].x,v[i].y,e[0].x-d[i].x,e[0].y-d[i].y);
//cr1=cross(v[i].x,v[i].y,e[1].x-d[i].x,e[1].y-d[i].y);
//sc1=sign(cr0);
//sc2=sign(cr1);
//if(sc1<=0&&sc2<=0)
//{
// init++;
//}
}

40
8.10/G - change.cpp Normal file
View File

@ -0,0 +1,40 @@
//G - ¸Ä¸ï´º·ç´µÂúµØ
//https://vjudge.net/contest/508277#problem/G
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
const int N=101;
double ans;
int n,j;
struct dot
{
int x,y;//int->double
} a[N];
double cross(double x1,double y1,double x2,double y2)
{
// printf("(%d,%d)(%d,%d):%d\n",x1,y1,x2,y2,x1*y2-x2*y1) ;
return x1*y2-x2*y1;
}
int main()
{
while(1)
{
scanf("%d",&n);
if(n==0) return 0;
ans=0;
memset(a,0,sizeof(dot)*(n+1));
for(int i=1; i<=n; i++)
{
scanf("%d%d",&a[i].x,&a[i].y);
}
for(int i=1; i<=n; i++)
{
j=i%n+1;
ans+=(cross(a[i].x,a[i].y,a[j].x,a[j].y)/2);
}
printf("%.1lf\n",ans);//Presentation Error
}
return 0;
}

54
8.10/H - area.cpp Normal file
View File

@ -0,0 +1,54 @@
//H - 面积
//https://vjudge.net/contest/508277#problem/H
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=101;
double s;
int n,i,j,tmp,e,m,t;
struct dot
{
int x,y;//int->double
} a[N];
double cross(double x1,double y1,double x2,double y2)
{
// printf("(%d,%d)(%d,%d):%d\n",x1,y1,x2,y2,x1*y2-x2*y1) ;
return x1*y2-x2*y1;
}
int gcd(int a,int b)
{
if(a<b) swap(a,b);//0~
while(b!=0)
{
tmp=a%b;
a=b;
b=tmp;
}
return a;
}
int main()
{
scanf("%d",&t);
m=t;
while(t--)
{
s=0,e=0;
scanf("%d",&n);//没有输入+吗m,n搞混
memset(a,0,sizeof(dot)*(n+1));
for(i=1; i<=n; i++)
{
scanf("%d%d",&a[i].x,&a[i].y);
j=i-1;
e+=gcd(abs(a[i].x),abs(a[i].y));
a[i].x+=a[j].x;
a[i].y+=a[j].y;
s+=cross(a[j].x,a[j].y,a[i].x,a[i].y)/2;
}
i=s+1-e/2.0;//Pick 定理 e=边上整个的点
printf("Scenario #%d:\n%d %d %.1lf\n\n",m-t,i,e,s);//两个空行Presentation Error
}
return 0;
}

36
8.10/ce.cpp Normal file
View File

@ -0,0 +1,36 @@
//G - ¸Ä¸ï´º·ç´µÂúµØ
//https://vjudge.net/contest/508277#problem/G
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=101;
double s;
int n,i,j,tmp,e,m,t;
struct dot
{
int x,y;//int->double
} a[N];
double cross(double x1,double y1,double x2,double y2)
{
// printf("(%d,%d)(%d,%d):%d\n",x1,y1,x2,y2,x1*y2-x2*y1) ;
return x1*y2-x2*y1;
}
int gcd(int a,int b)
{
// if(a<b) swap(a,b);//0~
while(b!=0)
{
tmp=a%b;
a=b;
b=tmp;
}
return a;
}
int main()
{
printf("%d",15556%0);
return 0;
}

BIN
8.10/向量、点积、叉积.pptx (Stored with Git LFS) Normal file

Binary file not shown.

BIN
8.10/课件补充资料:叉积的几何意义证明.docx (Stored with Git LFS) Normal file

Binary file not shown.

BIN
8.10/课件补充资料:平面向量的旋转.doc (Stored with Git LFS) Normal file

Binary file not shown.

BIN
8.11/多边形和凸包.pptx (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,6 @@
[{000214A0-0000-0000-C000-000000000046}]
Prop3=19,11
[InternetShortcut]
IDList=
URL=https://vjudge.net/contest/507591
HotKey=0

BIN
8.3/Treap-20220803.pptx (Stored with Git LFS) Normal file

Binary file not shown.

BIN
8.3/Treap原理和实现方法 - by 清北学堂 周源.pdf (Stored with Git LFS) Normal file

Binary file not shown.

BIN
8.3/堆20151130.ppt (Stored with Git LFS) Normal file

Binary file not shown.

BIN
8.3/平衡树20220803.pptx (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
8.4/伸展树的基本操作与应用20220804.pptx (Stored with Git LFS) Normal file

Binary file not shown.

BIN
8.4/运用伸展树解决数列维护问题.pdf (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,5 @@
[{000214A0-0000-0000-C000-000000000046}]
Prop3=19,11
[InternetShortcut]
IDList=
URL=https://vjudge.net/contest/507703

View File

@ -0,0 +1,6 @@
[{000214A0-0000-0000-C000-000000000046}]
Prop3=19,11
[InternetShortcut]
IDList=
URL=https://vjudge.net/contest/507772
HotKey=0

BIN
8.6/树形动态规划20220808.pptx (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,6 @@
[{000214A0-0000-0000-C000-000000000046}]
Prop3=19,11
[InternetShortcut]
IDList=
URL=https://vjudge.net/contest/507778
HotKey=0

BIN
8.8/树链剖分20220809.pptx (Stored with Git LFS) Normal file

Binary file not shown.

196
B - 树的统计Count.cpp Normal file
View File

@ -0,0 +1,196 @@
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=3e4+1,N2=N<<1,inf=0x3f3f3f3f;//N2 双向边记得*2
int to[N2],h[N2],ne[N2];
int nid[N],oid[N],top[N],w[N],dep[N],fa[N];
int siz[N],son[N];//子树节点数重边儿子siz最大的儿子
int qs[N<<2],qm[N<<2];
int t,u,v,w1,qu,n,cnt=0,maxson;
char opt[11];
#define ls rt<<1
#define rs rt<<1|1
#define mid ((l+r)>>1) //>>1写成>>2
#define lson ls,l,mid //l写成1
#define rson rs,mid+1,r
#define len (r-l+1)
void add(int u,int v)
{
to[++cnt]=v;
ne[cnt]=h[u];
h[u]=cnt;
}
//以下是线段树
int tot=0;
void build(int rt,int l,int r)
{
if(l==r)
{
qm[rt]=w[oid[l]];
qs[rt]=w[oid[l]];
// printf("l:%d,qm[%d]=w[%d]=%d\n",l,rt,oid[l],qm[rt]);
return;
}
// if(rt<=mid)
build(ls,l,mid);
// else
build(rs,mid+1,r);
qm[rt]=max(qm[ls],qm[rs]);
qs[rt]=qs[ls]+qs[rs];//bug TLE直接等于两个孩子相加
// printf("a[%d]=a[%d]%d/a[%d]%d\n",rt,ls,qm[ls],rs,qm[rs]);
}
inline int qmax(int rt,int l,int r,int L,int R)
{
if(L<=l&&r<=R)
{
// printf("[%d]",rt);
return qm[rt];
}
int res=-inf;
if(L<=mid)res=max(res,qmax(lson,L,R));
if(R>mid)res=max(res,qmax(rson,L,R));
return res;
}
inline int qsum(int rt,int l,int r,int L,int R)
{
if(L<=l&&r<=R)
{
// printf("[%d]",rt);
return qs[rt];
}
int res=0;
if(L<=mid)res+=qsum(lson,L,R);
if(R>mid)res+=qsum(rson,L,R);
return res;
}
//以上是线段树
inline int q(int u,int v,bool tag)
{
int res=0;
if(tag) res=-inf;
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]])
{
swap(u,v);
}
if(tag)res=max(res,qmax(1,1,n,nid[top[u]],nid[u]));
else res+=qsum(1,1,n,nid[top[u]],nid[u]);
// printf("(%d,%d,%d)",u,v,res);
u=fa[top[u]];
}
if(dep[u]>dep[v]) swap(u,v);
// printf("(%d,%d,%d)",nid[u],nid[v],res);
if(tag)res=max(res,qmax(1,1,n,nid[u],nid[v]));//son[u]->u边权放在儿子所以连接儿子和爸爸的路要排除爸爸
else res+=qsum(1,1,n,nid[u],nid[v]);//接上,给的是点权就不用
return res;
}
inline void dfs1(int u,int f,int deep)
{
fa[u]=f;
dep[u]=deep;
siz[u]=1;
for(int i=h[u]; i; i=ne[i])
{
int v=to[i];//bug int
if(v==f) continue;//bug 放后了
// printf("(wo[%d]=val[%d]=%d)\n",v,i,val[i]);
dfs1(v,u,deep+1);
siz[u]+=siz[v];
if(son[u]==0||siz[v]>siz[son[u]])
{
son[u]=v;
}
}
// printf("out:%d:fa:%d,dep:%d,siz:%d\n",u,f,deep,siz[u]);
}
inline void dfs2(int u,int tp)
{
nid[u]=++cnt;
oid[cnt]=u;
top[u]=tp;
// printf("%d:nid:%d,nw:%d,top:%d\n",u,cnt,wo[u],topf);
if(!son[u]) return;
dfs2(son[u],tp);
for(int i=h[u]; i; i=ne[i])
{
v=to[i];
if(v!=fa[u]&&v!=son[u])
{
dfs2(v,v);
}
}
}
inline void pushup(int rt)
{
qm[rt]=max(qm[ls],qm[rs]);
qs[rt]=qs[ls]+qs[rs];
}
inline void change(int u,int w1,int rt,int l,int r)
{
if(l==r)
{
qm[rt]=w1;
qs[rt]=w1;
// printf("u:%d,a[%d]=%d(l=r=%d)\n",u,rt,w1,l);
}
else
{
if(u<=mid)
{
change(u,w1,lson);
}
else change(u,w1,rson);
pushup(rt);
// printf("u:%d,a[%d]=a[%d]%d/a[%d]%d\n",u,rt,ls,a[ls],rs,a[rs]);
}
}
int main()
{
//freopen("10.in","r",stdin);
//freopen("out.txt","w",stdout);
scanf("%d",&n);
cnt=0;
// cout<<"\\";
for(int i=1; i<n; i++)
{
scanf("%d%d",&u,&v);// 多打一个%d c0000005 APPCRASH
// printf("(%d)",i);
add(u,v);
add(v,u);
}
for(int i=1; i<=n; i++)
{
scanf("%d",&w[i]);
}
dfs1(1,0,1);
cnt=0;
dfs2(1,1);
build(1,1,cnt);
scanf("%d",&qu);
while(qu--)
{
scanf("%s",opt);
scanf("%d%d",&u,&v);
if(opt[1]=='M')
{
printf("%d\n",q(u,v,1));
}
else if(opt[1]=='S')
{
printf("%d\n",q(u,v,0));
}
else
{
change(nid[u],v,1,1,cnt);
}
}
return 0;
}