• bzoj 3282 Tree


    3282: Tree

    Time Limit: 30 Sec  Memory Limit: 512 MB
    Submit: 1256  Solved: 549
    [Submit][Status][Discuss]

    Description

    给定N个点以及每个点的权值,要你处理接下来的M个操作。操作有4种。操作从0到3编号。点从1到N编号。

    0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和。保证x到y是联通的。

    1:后接两个整数(x,y),代表连接x到y,若x到Y已经联通则无需连接。

    2:后接两个整数(x,y),代表删除边(x,y),不保证边(x,y)存在。

    3:后接两个整数(x,y),代表将点X上的权值变成Y。

    Input

    第1行两个整数,分别为N和M,代表点数和操作数。

    第2行到第N+1行,每行一个整数,整数在[1,10^9]内,代表每个点的权值。

    第N+2行到第N+M+1行,每行三个整数,分别代表操作类型和操作所需的量。

    Output

    对于每一个0号操作,你须输出X到Y的路径上点权的Xor和。

     

    lct裸题。注意只要修改了儿子操作后要update,splay上的fa不代表是树中的fa,应该makeroot在access看他们是否成父子关系

     

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 #define maxn 3000020
      7 
      8 int child[maxn][2],fa[maxn],sum[maxn],rev[maxn],key[maxn];
      9 int n,m,stack[maxn],tops = -1;
     10 
     11 inline bool isroot(int x){
     12     return (child[fa[x]][0] != x && child[fa[x]][1] != x);
     13 }
     14 inline void reverse(int x){
     15     rev[x] ^= 1;
     16     swap(child[x][0],child[x][1]);
     17 }
     18 inline void pushdown(int x){
     19     if ( rev[x] ){
     20         if ( child[x][0] ) reverse(child[x][0]);
     21         if ( child[x][1] ) reverse(child[x][1]);
     22         rev[x] = 0;
     23     }
     24 }
     25 inline void update(int x){
     26     sum[x] = key[x] ^ sum[child[x][0]] ^ sum[child[x][1]];
     27 }
     28 inline void rotate(int x){
     29     int t = child[fa[x]][1] == x;
     30     int y  = fa[x] , z = child[x][1 - t];
     31     fa[x] = fa[y];
     32     if ( !isroot(y) ) child[fa[y]][child[fa[y]][1] == y] = x;
     33     fa[y] = x;
     34     child[x][1 - t] = y;
     35     if ( z ){
     36         fa[z] = y;
     37     }
     38     child[y][t] = z;
     39     update(y);
     40 }
     41 inline void splay(int x){
     42     stack[++tops] = x;
     43     for (int i = x ; !isroot(i) ; i = fa[i]) stack[++tops] = fa[i];
     44     while ( ~tops ) pushdown(stack[tops--]);
     45     while ( !isroot(x) ){
     46         int y = fa[x] , z = fa[y];
     47         if ( !((child[y][0] == x) ^ (child[z][0] == y)) && !isroot(y) ) rotate(y);
     48         else rotate(x);
     49         if ( isroot(x) ) break;
     50         rotate(x);
     51     }
     52     update(x);
     53 }
     54 inline void access(int x){
     55     int t = 0;
     56     for (;x;x = fa[x])
     57            splay(x) , child[x][1] = t ,update(x), t = x;
     58 }
     59 inline void makeroot(int x){
     60     access(x);
     61        splay(x);
     62        reverse(x);
     63 }
     64 inline int findroot(int x){
     65     access(x);
     66     splay(x);
     67   //  pushdown(x); 在splay时已经pushdown过了
     68     while ( child[x][0] ) x = child[x][0]; //pushdown(x);
     69     return x;
     70 }
     71 inline void link(int x,int y){
     72     makeroot(y);
     73     fa[y] = x;
     74 }    
     75 inline void cut(int x,int y){
     76     makeroot(x);
     77     access(y);
     78     splay(y);
     79     if ( child[y][0] == x ) child[y][0] = fa[x] = 0;
     80     else if ( child[y][1] == x ) child[y][1] = fa[x] = 0;
     81     update(y);
     82 }
     83 void print(){
     84     for (int i = 1 ; i <= n ; i++) cout<<i<<" fa "<<fa[i]<<" child "<<child[i][0]<<" "<<child[i][1]<<endl;
     85 }
     86 int main(){
     87     freopen("input.txt","r",stdin);
     88     scanf("%d %d",&n,&m);
     89     for (int i = 1 ; i <= n ; i++) scanf("%d",&sum[i]) , key[i] = sum[i];
     90     for (int i = 1 ; i <= m ; i++){
     91         int x,y,t;
     92         scanf("%d %d %d",&t,&x,&y);
     93         if ( t == 0 ){
     94             makeroot(x);
     95             access(y);
     96             splay(y);
     97             printf("%d
    ",sum[y]);
     98         }
     99         else if ( t == 1 ){
    100             if ( findroot(x) != findroot(y) ){
    101                 link(x,y);
    102             }
    103         }
    104         else if ( t == 2 ){
    105             cut(x,y);
    106         }
    107         else if ( t == 3 ){
    108             splay(x);
    109             key[x] = y;
    110             update(x);
    111         }
    112     }
    113     return 0;
    114 }
  • 相关阅读:
    2018-09-13 代码翻译尝试-使用Roaster解析和生成Java源码
    2018-09-10 使用现有在线翻译服务进行代码翻译的体验
    2018-09-06 Java实现英汉词典API初版发布在Maven
    2018-08-29 浏览器插件实现GitHub代码翻译原型演示
    2018-08-27 使用JDT核心库解析JDK源码后初步分析API命名
    2018-08-11 中文代码示例之Spring Boot 2.0.3问好
    2018-08-24 中文代码之Spring Boot对H2数据库简单查询
    2018-08-22 为中文API的简繁转换库添加迟到的持续集成
    2018-08-21 中文关键词替换体验页面原型
    vim打开不同的文件
  • 原文地址:https://www.cnblogs.com/zqq123/p/5308956.html
Copyright © 2020-2023  润新知