交上去全RE 但是下下来的数据和样例都过了 代码:
#include <map>
#include <cmath>
#include <ctime>
#include <queue>
#include <deque>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <functional>
#define ll long long
using namespace std;
bool flg;
char ch;
inline int rd(){
int res = 0, fl = 1;
char c = getchar();
while(!isdigit(c)){
if(c == '-') fl = -1;
c = getchar();
}
while(isdigit(c)){
res = (res << 3) + (res << 1) + c - '0';
c = getchar();
}
return res * fl;
}
inline int in() {
char ich = getchar();
int intmp = 0, insign = 1;
while (((ich < '0') || (ich > '9')) && ((ich != '-'))) {
ich = getchar();
}
if (ich == '-') {
insign = -1;
ich = getchar();
}
while ((ich <= '9') && (ich >= '0')) {
intmp *= 10;
intmp += ich - '0';
ich = getchar();
}
return intmp * insign;
}
int P, n, m, R, l, r, op, a[100010], c;
struct Node{
int l, r;
ll val, tag;
Node *ls, *rs;
bool InRange(const int L, const int R){
return L <= l && r <= R;
}
bool OutofRange(const int L, const int R){
return l > R || L > r;
}
void maketag(const int x){
val += (r - l + 1) * x;
tag += x;
}
void pushdown(){
if(ls != NULL){
ls->maketag(tag);
}
if(rs != NULL){
rs->maketag(tag);
}
tag = 0;
}
void pushup(){
val = ls->val + rs->val;
val %= P;
}
void upd(const int L, const int R, const int x){
if(InRange(L, R)) maketag(x);
else if(!OutofRange(L, R)){
pushdown();
ls->upd(L, R, x);
rs->upd(L, R, x);
pushup();
}
}
ll query(const int L, const int R){
if(InRange(L, R)) return val;
else if(!OutofRange(L, R)){
pushdown();
ll res = 0;
if(ls != NULL){
res += ls->query(L, R);
}
if(rs != NULL){
res += rs->query(L, R);
}
res %= P;
pushup();
return res;
}
}
}Mem[200010], *pool = Mem, *rot;
const int maxn = 100010;
struct Edge{
int to, nxt;
}ed[200010];
int en, fst[maxn];
int sze[maxn], dep[maxn], son[maxn], tp[maxn], tot, pst[maxn], fa[maxn], crt[maxn], id[maxn];
void add(int u, int v){
ed[++en].to = v;
ed[en].nxt = fst[u];
fst[u] = en;
}
Node* build(const int L, const int R){
Node *u = ++pool;
u->l = L;
u->r = R;
u->tag = 0;
if(L == R){
u->val = a[pst[L]];
}
else {
int M = (L + R) >> 1;
u->ls = build(L, M);
u->rs = build(M + 1, R);
u->pushup();
}
return u;
}
void dfs(int x){
sze[x] = 1;
for(int e = fst[x]; e; e = ed[e].nxt){
int v = ed[e].to;
if(v == fa[x]) continue;
fa[v] = x;
dep[v] = dep[x] + 1;
dfs(v);
sze[x] += sze[v];
if(sze[v] > sze[son[x]]) son[x] = v;
}
}
void dfs_rewrite(int x, int top){
tp[x] = top;
id[x] = ++tot;
pst[tot] = x;
if(son[x]) dfs_rewrite(son[x], top);
for(int e = fst[x]; e; e = ed[e].nxt){
int v = ed[e].to;
if(v != fa[x] && v != son[x]) dfs_rewrite(v, v);
}
crt[x] = tot;
}
ll Ask(int x, int y){
ll res = 0;
while(tp[x] != tp[y]){
if(dep[tp[x]] < dep[tp[y]]) swap(x, y);
res += rot->query(id[tp[x]], id[x]);
res %= P;
x = fa[tp[x]];
}
if(dep[x] > dep[y]) swap(x, y);
res += rot->query(id[x], id[y]);
res %= P;
return res;
}
void Change(int x, int y, int c){
while(tp[x] != tp[y]){
if(dep[tp[x]] < dep[tp[y]]) swap(x, y);
rot->upd(id[tp[x]], id[x], c);
x = fa[tp[x]];
}
if(dep[x] > dep[y]) swap(x, y);
rot->upd(id[x], id[y], c);
}
void ChangeTree(int x, int c){
rot->upd(id[x], crt[x], c);
}
ll AskTree(int x){
ll res = rot->query(id[x], crt[x]);
res %= P;
return res;
}
int main() {
// freopen("P3384_1.in","r",stdin);
// freopen("P3384_1.ans","w",stdout);
n = rd(); m = rd(); R = rd(); P = rd();
for(int i = 1; i <= n; ++i) a[i] = rd();
for(int i = 1; i < n; ++i){
l = rd(); r = rd();
add(l, r); add(r, l);
}
dfs(R);
dfs_rewrite(R, R);
rot = build(1, tot);
for(int i = 1; i <= m; ++i){
op = rd();
if(op == 1){
l = rd(); r = rd(); c = rd();
Change(l, r, c);
}
if(op == 2){
l = rd(); r = rd();
printf("%lld\n", Ask(l, r) % P);
}
if(op == 3){
l = rd(); c = rd();
ChangeTree(l, c);
}
if(op == 4){
l = rd();
printf("%lld\n", AskTree(l) % P);
}
}
return 0;
}