蒟蒻求助,只能7分
查看原帖
蒟蒻求助,只能7分
169928
YRZ001030楼主2020/4/30 22:29

就过了第一组数据,真的找不出了 哭

#include"stdio.h"
#include"string.h"
#include"algorithm"
using namespace std;
typedef long long ll;
inline int read(){
    int f = 1, x = 0;char ch = getchar();
    while (ch > '9' || ch < '0'){if (ch == '-')f = -f;ch = getchar();}
    while (ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
    return x * f;
}

const int N = 200010;
const ll INF = 1e19;
int n,q,root,mod,m;
int head[N],ver[N],Next[N],tot;///树的结构存储
int val[N];///存储每个结点的信息
int d[N],son[N],far[N],Size[N];///结点的深度,重儿子,祖先
int a[N];
int sum[N * 4];///线段树上的结点值,maxx,sum值
int dfn[N],top[N],id[N];///存储dfs序,top是条链的祖先,id是每个结点在dfn中序列的下标位置
int cnt;///表示的是dfs序列的最后一个位置
int lazy[N * 4];int maxx = 0;

void add(int x,int y){ ///添加树边
    ver[++ tot] = y;  Next[tot] = head[x]; head[x] = tot;
}

void Build_Tree(int id,int l,int r)
{
    sum[id] = 0;
    if(l == r){
        sum[id] = val[dfn[l]]; return ;
    }
    int mid = (l + r) >> 1;
    Build_Tree(id * 2,l,mid);
    Build_Tree(id * 2 + 1,mid + 1,r);
    sum[id] = sum[id * 2] ^ sum[id * 2 + 1];
    return ;
}

void push_down(int id,int L,int R){
    if(lazy[id]){
        int mid = (L + R) >> 1;
        lazy[id * 2] += lazy[id]; lazy[id * 2 + 1] += lazy[id];
        sum[id * 2] += lazy[id] * (mid - L + 1); sum[id * 2 + 1] += lazy[id] * (R - mid);
        lazy[id] = 0;
    } return ;
}

int Query_sum(int id,int L,int R,int l,int r)///查询[l,r]区间和
{
    if(l <= L && r >= R) return sum[id];
    int mid = (L + R) >> 1; int ans = 0;
    if(l <= mid) ans ^= Query_sum(id * 2,L,mid,l,r);
    if(r > mid) ans ^= Query_sum(id * 2 + 1,mid + 1,R,l,r);
    return ans;
}

void update(int id,int L,int R,int pos,int v,int x){
    if(L == R) {
        sum[id] = v; return ;
    }
    int mid = (L + R) >> 1;
    if(pos <= mid) update(id * 2,L,mid,pos,v,x);
    if(pos > mid) update(id * 2 + 1,mid + 1,R,pos,v,x);
    sum[id] = sum[id * 2] ^ sum[id * 2 + 1];
    return ;
}
void Update(int x,int y){
    int pos = id[x];
    update(1,1,n,pos,y,x);
}

int Query(int x,int y){
       int fx = top[x],fy = top[y];
       int ans = 0,ttt;
       while(fx != fy){
         if(d[fx] > d[fy]) {
            ttt = Query_sum(1,1,n,id[fx],id[x]);
            ans ^= ttt;
            x = far[fx]; fx = top[x];
         } else{
            ttt = Query_sum(1,1,n,id[fy],id[y]);
            ans ^= ttt;
            y = far[fy]; fy = top[y];
         }
        }
        if(d[x] < d[y]){
                ttt = Query_sum(1,1,n,id[x],id[y]);  ans ^= ttt;
        }
        else {
            ttt = Query_sum(1,1,n,id[y],id[x]);  ans ^= ttt;
        }
      return ttt;
}
void dfs1(int u,int f,int dep)///dfs1指在处理d数组,son数组,far数组,Size数组
{
    d[u] = dep; far[u] = f;
    Size[u] = 1; son[u] = -1;
    for(int i = head[u]; i; i = Next[i]){
        int v = ver[i];
        if(v == f) continue;
        dfs1(v,u,dep+1);
        Size[u] += Size[v];
        if(son[u] == -1 || Size[son[u]] < Size[v])
           son[u] = v;
    }
}

void dfs2(int u,int T)///旨在处理重链,和dfs序列
{
    dfn[++ cnt] = u;id[u] = cnt;
    top[u] = T;
    if(son[u] == -1) return ;
    dfs2(son[u],T);
    for(int i = head[u]; i; i = Next[i]){
        int v = ver[i];
        if(v != son[u] && v != far[u]){
            dfs2(v,v);
        }
    }
}

int main()
{
    n = read();  m = read();
    for(int i = 1; i <= n; i ++)
        val[i] = read();
    for(int i = 1; i < n; i ++){
        int x,y; scanf("%d%d",&x,&y);
        add(x,y); add(y,x);
    }
    q = m;
    cnt = 0; root = 1;
    dfs1(root,root,1);
    dfs2(root,root);
    Build_Tree(1,1,n);
    while(q --){
       int op = read(),x = read(),y = read();
       if(op == 1) Update(x,y);
       else {
          printf("%d\n",Query(x,y));
       }
    }
}

2020/4/30 22:29
加载中...