zoukankan      html  css  js  c++  java
  • COJ 1006 树上操作

    传送门:http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=979

    WZJ的数据结构(六)
    难度级别:D; 运行时间限制:1000ms; 运行空间限制:51200KB; 代码长度限制:2000000B
    试题描述

    给你一棵N个节点的无根树,边之间有权值。请你设计一个数据结构,进行以下两种操作:

    1.修改:给你a、b,将第a条边的权值改为b。

    2.询问:给你a、b,输出从a到b路径上的最大值、最小值与权值和,如果a=b,输出"error"。

    输入
    第一行为一个正整数N。
    接下来N-1行为每一条边,每行3个正整数a,b,c,表示有一条从a到b权值为c的边(从1开始编号)。
    第N+1行为一个正整数Q,表示Q次操作。
    接下来Q行为每一次询问,每行3个正整数t,a,b,若t=1表示询问,t=0表示修改。
    输出
    对于每一次询问,输出三个正整数,即最大值、最小值与权值和,如果a=b,输出"error"。
    输入示例

    1 2 4
    1 4 5
    3 4 6
    2 5 7
    4
    1 1 5
    1 2 5
    0 1 2
    1 1 5
    输出示例
    7 4 11
    7 7 7
    7 2 9
    其他说明
    1<=N,Q<=50000
    1<=c<=1000
    询问中的1<=a,b<=N
    修改中的1<=a<=N-1,1<=b<=1000

    题解:懒得写树链剖分了LCT走起

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<algorithm>
      5 #include<queue>
      6 #include<cstring>
      7 #define PAU putchar(' ')
      8 #define ENT putchar('
    ')
      9 using namespace std;
     10 const int maxn=100000+10,inf=-1u>>1;
     11 inline int read(){
     12     int x=0,sig=1;char ch=getchar();
     13     while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();}
     14     while(isdigit(ch))x=10*x+ch-'0',ch=getchar();
     15     return x*=sig;
     16 }
     17 inline void write(int x){
     18     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
     19     int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
     20     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
     21 }
     22 struct node {
     23     int x,mi,mx,sm,set;bool rev;
     24     node *ch[2],*fa;
     25     inline void add_rev_tag(){
     26         swap(ch[0],ch[1]);rev^=1;return;
     27     }
     28     inline void add_set_tag(int a){
     29         x=set=a;
     30         if(mi!=inf) mi=set;
     31         if(mx!=-inf) mx=set;
     32     }
     33     inline void down(){
     34         if(rev){
     35             if(ch[0]) ch[0]->add_rev_tag();
     36             if(ch[1]) ch[1]->add_rev_tag();
     37             rev=0;
     38         }
     39         if(set){
     40             if(ch[0]) ch[0]->add_set_tag(set);
     41             if(ch[1]) ch[1]->add_set_tag(set);
     42             set=0;
     43         }
     44         return;
     45     }
     46     inline void update(){
     47         sm=x;mi=inf;mx=-inf;
     48         if(ch[0]) sm+=ch[0]->sm,mi=min(mi,ch[0]->mi),mx=max(mx,ch[0]->mx);
     49         if(ch[1]) sm+=ch[1]->sm,mi=min(mi,ch[1]->mi),mx=max(mx,ch[1]->mx);
     50         if(!x) return;
     51         mi=min(x,mi);
     52         mx=max(x,mx);
     53         return;
     54     }
     55 }lct[maxn];
     56 inline int get_parent(node *x,node *&fa){return (fa=x->fa)?fa->ch[0]==x?0:fa->ch[1]==x?1:-1:-1;}
     57 inline void rotate(node *x){
     58     int t1,t2;
     59     node *fa,*gfa;
     60     t1=get_parent(x,fa);
     61     t2=get_parent(fa,gfa);
     62     if ((fa->ch[t1]=x->ch[t1^1])) fa->ch[t1]->fa=fa;
     63     x->ch[t1^1]=fa;fa->fa=x;x->fa=gfa;
     64     if (t2!=-1) gfa->ch[t2]=x;
     65     fa->update();return;
     66 }
     67 inline void pushdown(node *x){
     68     static node *stack[maxn];
     69     int cnt=0;
     70     while(1){
     71         stack[cnt++]=x;
     72         node *fa=x->fa;
     73         if (!fa || (fa->ch[0]!=x && fa->ch[1]!=x)) break;
     74         x=fa;
     75     }
     76     while(cnt--) stack[cnt]->down();
     77     return;
     78 }
     79 inline node * splay(node *x){
     80     pushdown(x);
     81     while(1){
     82         int t1,t2;
     83         node *fa,*gfa;
     84         t1=get_parent(x,fa);
     85         if(t1==-1) break;
     86         t2=get_parent(fa,gfa);
     87         if(t2==-1){
     88             rotate(x);break;
     89         } else if (t1==t2){
     90             rotate(fa);rotate(x);
     91         } else{
     92             rotate(x);rotate(x);
     93         }
     94     }
     95     x->update();
     96     return x;
     97 }
     98 inline node * access(node *x){
     99     node *ret=NULL;
    100     while (x) splay(x)->ch[1]=ret,(ret=x)->update(),x=x->fa;
    101     return ret;
    102 }
    103 inline void makeroot(int x){access(lct+x)->add_rev_tag();}
    104 inline void link(int u,int v){
    105     makeroot(u);splay(lct+u)->fa=lct+v;return;
    106 }
    107 int n,q;
    108 int main(){
    109     n=read();
    110     int i;
    111     int lim=n<<1;
    112     for(i=1;i<=lim;i++) {
    113         lct[i]=(node){0,inf,-inf,0,0,0};
    114     }
    115     for(i=1;i<n;i++){
    116         int u,v,w;
    117         u=read();v=read();
    118         link(u,i+n);link(v,i+n);lct[i+n].add_set_tag(read());
    119     }
    120     q=read();
    121     int x,y,c;
    122     while(q--){
    123         c=read();x=read();y=read();
    124         if(c==0) makeroot(x+n),access(x+n+lct)->add_set_tag(y);
    125         else{
    126             if(x==y){puts("error");continue;}
    127             makeroot(x);node*t=access(y+lct);
    128             write(t->mx);PAU;write(t->mi);PAU;write(t->sm);ENT;
    129         }
    130     }
    131     return 0;
    132 }
  • 相关阅读:
    WCF基础教程之开篇:创建、测试和调用WCF
    程序员必须知道的几个Git代码托管平台
    2015继续任性——不会Git命令,照样玩转Git
    何必苦等VS2015?来看看VS2013下实现移动端的跨平台开发
    Android Studio 1.0.2项目实战——从一个APP的开发过程认识Android Studio
    (转)创建Graphics的三种方法
    sql自增长列重新从1计算
    IT之人生感悟
    c# 高效率导出多维表头excel
    SQL 之witn as语法
  • 原文地址:https://www.cnblogs.com/chxer/p/4525824.html
Copyright © 2011-2022 走看看