zoukankan      html  css  js  c++  java
  • 【BZOJ2157】旅游 LCT

    模板T,SB的DMoon。。其实样例也是中国好样例。。。一开始不会复制,yangyang:找到“sample input”按住shift,按page down。。。。

      1 #include <iostream>
      2 #include <cstdio>
      3 #define inf 0x7fffffff
      4 #define N 20010
      5 #define M 20010
      6 using namespace std;
      7 int n,m;
      8 struct node *null;
      9 struct node 
     10 {
     11     node *fa,*ch[2];
     12     //node(int x,int flag);
     13     int maxn,minn,data,sum;
     14     bool rev,rev_data,ie;
     15     bool chr() {return this==fa->ch[1];}
     16     bool isrt() {return this!=fa->ch[1] && this !=fa->ch[0];}
     17     void setc(node *x,int t) {this->ch[t]=x; x->fa=this;}
     18     void push_up();
     19     void push_down();
     20 }pool[N+M],*pt=pool,*e[M],*p[N];
     21 void node::push_up()
     22 {
     23     if (this==null) return;
     24     sum=ch[1]->sum+ch[0]->sum+data*ie;
     25     maxn=max(ch[1]->maxn,ch[0]->maxn); if (ie) maxn=max(maxn,data);
     26     minn=min(ch[1]->minn,ch[0]->minn); if (ie) minn=min(minn,data); 
     27 }
     28 void node::push_down()
     29 {
     30     if (this==null) return;
     31     if (!isrt()) fa->push_down();
     32     if (rev)
     33     {
     34         if (ch[0]!=null) ch[0]->rev^=1;
     35         if (ch[1]!=null) ch[1]->rev^=1;
     36         swap(ch[0],ch[1]);
     37         rev=0;
     38     }
     39     if (rev_data)
     40     {
     41         if (ch[0]!=null)
     42         {
     43             int k=ch[0]->maxn;
     44             ch[0]->rev_data^=1;
     45             ch[0]->data=-ch[0]->data;
     46             ch[0]->sum=-ch[0]->sum;
     47             ch[0]->maxn=-ch[0]->minn;
     48             ch[0]->minn=-k;
     49         }
     50         if (ch[1]!=null)
     51         {
     52             int k=ch[1]->maxn;
     53             ch[1]->rev_data^=1;
     54             ch[1]->sum=-ch[1]->sum;
     55             ch[1]->maxn=-ch[1]->minn;
     56             ch[1]->minn=-k;
     57             ch[1]->data=-ch[1]->data;
     58         }
     59     //    swap(ch[0],ch[1]);// 注意!!! 
     60         rev_data=0;
     61     }
     62 }
     63 namespace LCT
     64 {
     65     node *NewNode(int x,int flag) 
     66     {
     67         node *r=pt++;
     68         r->fa=r->ch[0]=r->ch[1]=null;
     69         r->data=r->sum=x; r->ie=flag;
     70         if  (flag) r->maxn=r->minn=x;
     71         else r->maxn=-inf,r->minn=inf;
     72         r->rev=r->rev_data=0;
     73         return r;
     74     }
     75     void rotate(node *x)
     76     {
     77         node *r=x->fa;
     78         if (r==null || x==null) return;
     79         x->push_down(); r->push_down();
     80         bool t=x->chr();
     81         if (r->isrt()) x->fa=r->fa; // !!!在这里坑了好几次了 
     82         else r->fa->setc(x,r->chr());
     83         r->setc(x->ch[t^1],t);
     84         x->setc(r,!t);
     85         r->push_up(); x->push_up();
     86     }
     87     void Splay(node *x)
     88     {
     89         //if (x==null) return;
     90         x->push_down();
     91         for (;!x->isrt();rotate(x))
     92             if (!x->fa->isrt())
     93                 if (x->chr()==x->fa->chr()) rotate(x->fa);
     94                 else rotate(x);
     95         x->push_up();
     96     }    
     97     void Access(node *x)
     98     {
     99         node *r=null;
    100         for (;x!=null;r=x,x=x->fa)
    101         {
    102             Splay(x);
    103             x->ch[1]=r;
    104         }
    105     }
    106     void MoveRoot(node *x) {Access(x); Splay(x); x->rev^=1;}
    107     void Split(node *x,node *y) {MoveRoot(x); Access(y); Splay(y);}
    108     void Link(node *x,node *y) {MoveRoot(x); x->fa=y;}
    109     void Cut(node *x,node *y) {Split(x,y); y->ch[0]->fa=null; y->ch[0]=null;}
    110     void Change(node *x,int v) {Splay(x); x->data=v; x->push_up();}
    111     void Data_Rev(node *x,node *y) {Split(x,y); int k=y->maxn; y->data=-y->data; y->sum=-y->sum; y->maxn=-y->minn; y->minn=-k; y->rev_data^=1; }
    112     int Query_Sum(node *x,node *y) {Split(x,y); return y->sum;}
    113     int Query_Max(node *x,node *y) {Split(x,y); return y->maxn;}
    114     int Query_Min(node *x,node *y) {Split(x,y); return y->minn;}
    115 }
    116 inline int read()
    117 {
    118     char c;
    119     int ans=0,f=1;
    120     while (!isdigit(c=getchar())) {if (c=='-') f=-1;}
    121     ans=c-'0';
    122     while (isdigit(c=getchar())) ans=ans*10+c-'0';
    123     return ans*f;
    124 }
    125 void init() 
    126 {
    127     null=pt++;
    128     null->fa=null->ch[0]=null->ch[1]=null;
    129     null->data=null->sum=0;
    130     null->rev=null->rev_data=null->ie=0;
    131     null->maxn=-inf; null->minn=inf;
    132 }
    133 using namespace LCT;
    134 int main()
    135 {
    136 //    freopen("travel.in","r",stdin);
    137 //    freopen("travel.out","w",stdout);
    138     int x,y,z;
    139     n=read();
    140     init();
    141     for (int i=0;i<n;i++) p[i]=NewNode(0,0);
    142     for (int i=1;i<n;i++)
    143     {
    144         x=read(); y=read(); z=read();
    145         e[i]=NewNode(z,1);
    146         Link(p[x],e[i]);Link(e[i],p[y]);
    147     }
    148     m=read();
    149     char s[10];
    150     for (int i=1;i<=m;i++)
    151     {
    152         scanf("%s",s);
    153         x=read(); y=read();
    154         if (s[0]=='C') Change(e[x],y);
    155         if (s[0]=='N') Data_Rev(p[x],p[y]);
    156         if (s[0]=='S') printf("%d
    ",Query_Sum(p[x],p[y]));
    157         if (s[0]=='M')
    158             if (s[1]=='A')    printf("%d
    ",Query_Max(p[x],p[y]));
    159             else printf("%d
    ",Query_Min(p[x],p[y]));
    160     }
    161     return 0;
    162 }
    View Code

    Description

    Ray 乐忠于旅游,这次他来到了T 城。T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接。为了方便游客到达每个景点但又为了节约成本,T 城的任意两个景点之间有且只有一条路径。换句话说, T 城中只有N − 1 座桥。Ray 发现,有些桥上可以看到美丽的景色,让人心情愉悦,但有些桥狭窄泥泞,令人烦躁。于是,他给每座桥定义一个愉悦度w,也就是说,Ray 经过这座桥会增加w 的愉悦度,这或许是正的也可能是负的。有时,Ray 看待同一座桥的心情也会发生改变。现在,Ray 想让你帮他计算从u 景点到v 景点能获得的总愉悦度。有时,他还想知道某段路上最美丽的桥所提供的最大愉悦度,或是某段路上最糟糕的一座桥提供的最低愉悦度。

    Input

    输入的第一行包含一个整数N,表示T 城中的景点个数。景点编号为 0...N − 1。接下来N − 1 行,每行三个整数u、v 和w,表示有一条u 到v,使 Ray 愉悦度增加w 的桥。桥的编号为1...N − 1。|w| <= 1000。输入的第N + 1 行包含一个整数M,表示Ray 的操作数目。接下来有M 行,每行描述了一个操作,操作有如下五种形式: C i w,表示Ray 对于经过第i 座桥的愉悦度变成了w。 N u v,表示Ray 对于经过景点u 到v 的路径上的每一座桥的愉悦度都变成原来的相反数。 SUM u v,表示询问从景点u 到v 所获得的总愉悦度。 MAX u v,表示询问从景点u 到v 的路径上的所有桥中某一座桥所提供的最大愉悦度。 MIN u v,表示询问从景点u 到v 的路径上的所有桥中某一座桥所提供的最小愉悦度。测试数据保证,任意时刻,Ray 对于经过每一座桥的愉悦度的绝对值小于等于1000。

    Output

    对于每一个询问(操作S、MAX 和MIN),输出答案。

    Sample Input

    Sample Output

    —Anime Otaku Save The World.
  • 相关阅读:
    6410实现网卡(DM9000A)收发功能及ARP协议实现
    Shuffling Machine和双向链表
    Have Fun with Numbers及循环链表(约瑟夫问题)
    Tiny6410 LCD设置
    RAM与内存
    inet_addr解析
    map容器find用法
    WinSock编程(TCP)
    Python 时间序列作图及注释
    无法打开之前cuda的vs项目,打开之后变灰色
  • 原文地址:https://www.cnblogs.com/DMoon/p/5334061.html
Copyright © 2011-2022 走看看