这道题调了那么久居然是最后的judge错了……
没有考虑m=0和m=1的情况
以
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=100000+5;
int n,m;
int a[N];
int to[2*N],nxt[2*N],head[N],etot;
int dep[N],fat[N],son[N],size[N];
int top[N],in[N],seq[N],idc;
int prime[N],siz;bool isprime[N];
struct node{
node *ls,*rs;
int vsum,del,chg;
void pushdown(int lf,int rg){
int mid=(lf+rg)>>1;
if(chg!=-1){
ls->chg=chg;
rs->chg=chg;
ls->del=0;
rs->del=0;
ls->vsum=(mid-lf+1)*chg;
rs->vsum=(rg-mid)*chg;
chg=-1;
}
if(del!=0){
ls->del+=del;
rs->del+=del;
ls->vsum+=(mid-lf+1)*del;//(ls->del);
rs->vsum+=(rg-mid)*del;//(rs->del);
//若子节点之前也有del说明之前也更新到过它,那del已经加给它过了
//这次只用加这次的del即可
del=0;
}
}
}pool[2*N+5],*tail=pool,*rt;
void adde(int u,int v)
{
to[++etot]=v;
nxt[etot]=head[u];
head[u]=etot;
}
void dfs1(int u,int fa)
{
dep[u]=dep[fa]+1;
fat[u]=fa;
size[u]=1;
for(int i=head[u];i;i=nxt[i]){
int v=to[i];
if(v==fa) continue;
dfs1(v,u);
if(son[u]==-1||size[v]>size[son[u]]) son[u]=v;
size[u]+=size[v];
}
}
void dfs2(int u,int tp)
{
top[u]=tp;
in[u]=++idc;
seq[idc]=u;
if(son[u]!=-1) dfs2(son[u],tp);
for(int i=head[u];i;i=nxt[i]){
int v=to[i];
if(v==fat[u]||v==son[u]) continue;
dfs2(v,v);
}
}
node *build(int lf,int rg)
{
node *nd=++tail;
if(lf==rg){
nd->vsum=a[seq[lf]];
nd->del=0;
nd->chg=-1;
return nd;
}
int mid=(lf+rg)>>1;
nd->ls=build(lf,mid);
nd->rs=build(mid+1,rg);
nd->del=0;
nd->chg=-1;
nd->vsum=nd->ls->vsum+nd->rs->vsum;
// nd->update();
return nd;
}
void modify_del(node *nd,int L,int R,int lf,int rg,int del)
{
if(L<=lf&&rg<=R){
//这个点已经没有原来的chg del的干扰了
nd->vsum+=del*(rg-lf+1);
nd->del+=del;
return;
//有标记的意义在于表示它的标记还没有向下传递,但是它已经被标记更新了
}
nd->pushdown(lf,rg);
int mid=(lf+rg)>>1;
if(L<=mid) modify_del(nd->ls,L,R,lf,mid,del);
if(R>mid) modify_del(nd->rs,L,R,mid+1,rg,del);
nd->vsum=nd->ls->vsum+nd->rs->vsum;
}
void modify_del(int u,int v,int del)
{
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
modify_del(rt,in[top[u]],in[u],1,n,del);
u=fat[top[u]];
}
if(dep[u]<dep[v]) swap(u,v);
modify_del(rt,in[v],in[u],1,n,del);
}
void modify_chg(node *nd,int L,int R,int lf,int rg,int val)
{
if(L<=lf&&rg<=R){
nd->del=0;
nd->chg=val;
nd->vsum=val*(rg-lf+1);
return;
}
nd->pushdown(lf,rg);
int mid=(lf+rg)>>1;
if(L<=mid) modify_chg(nd->ls,L,R,lf,mid,val);
if(R>mid) modify_chg(nd->rs,L,R,mid+1,rg,val);
nd->vsum=nd->ls->vsum+nd->rs->vsum;
}
void modify_chg(int u,int v,int val)
{
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
modify_chg(rt,in[top[u]],in[u],1,n,val);
u=fat[top[u]];
}
if(dep[u]<dep[v]) swap(u,v);
modify_chg(rt,in[v],in[u],1,n,val);
}
int query(node *nd,int L,int R,int lf,int rg)
{
if(L<=lf&&rg<=R)
return nd->vsum;
nd->pushdown(lf,rg);
int mid=(lf+rg)>>1;
int ans=0;
if(L<=mid) ans+=query(nd->ls,L,R,lf,mid);
if(R>mid) ans+=query(nd->rs,L,R,mid+1,rg);
nd->vsum=nd->ls->vsum+nd->rs->vsum;
return ans;
}
int query(int u,int v)
{
int ans=0;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
ans+=query(rt,in[top[u]],in[u],1,n);
u=fat[top[u]];
}
if(dep[u]<dep[v]) swap(u,v);
ans+=query(rt,in[v],in[u],1,n);
return ans;
}
bool judge(int x)
{
if(x==2) return 0;
if(!(x%2)) return 1;
if(x-2<=100000){
if(isprime[x-2]) return 1;
else return 0;
}
else {
for(int i=2;i*i<=x-2;i++)
if((x-2)%i==0) return 0;
return 1;
}
}
void euler(int primesize)
{
isprime[1]=0;
memset(isprime,1,sizeof(isprime));
for(int i=2;i<=primesize;i++){
if(isprime[i]) prime[++siz]=i;
for(int j=1;prime[j]*i<=primesize&&j<=siz;j++){
isprime[i*prime[j]]=0;
if(!(i%prime[j])) break;
}
}
}
int main()
{
freopen("japari.in","r",stdin);
freopen("japari.out","w",stdout);
euler(100000);
memset(son,-1,sizeof(son));
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
adde(u,v),adde(v,u);
}
dfs1(1,1);
dfs2(1,1);
rt=build(1,n);
while(m--){
int opt,x,y,v;
scanf("%d",&opt);
if(opt==1){
scanf("%d%d%d",&x,&y,&v);
modify_del(x,y,v);
}
if(opt==2){
scanf("%d%d%d",&x,&y,&v);
modify_chg(x,y,v);
}
if(opt==3){
scanf("%d%d",&x,&y);
int m=query(x,y);
if(judge(m)) printf("SUGOI\n");
else printf("TANOSHI\n");
}
}
return 0;
}