• bzoj 2157 旅行


    题目大意:

    一个树 支持以下五种操作

    C i w,表示对于经过第i条边的权值变成了w

    N u v,表示u 到v 的路径上的所有边的权值都变成原来的相反数。

    SUM u v,表示询问从u 到v 所获得的边权和

    MAX u v,表示询问从u 到v 的路径上的边权最大值

    MIN u v,表示询问从u 到v 的路径上的边权最小值

    思路:

    树链剖分

    把每条边的权值都记在深度靠下的点里

    然后对于线段树打一个tag记录是否要进行N操作

    对于这个tag每次update时要XOR!!!

    因为有可能连续N两次

    然后就正常操作了

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<cstdlib>
      5 #include<cstring>
      6 #include<algorithm>
      7 #include<vector>
      8 #include<queue>
      9 #define inf 2139062143
     10 #define ll long long
     11 #define MAXN 20101  
     12 using namespace std;
     13 inline int read()
     14 {
     15     int x=0,f=1;char ch=getchar();
     16     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
     17     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
     18     return x*f;
     19 }
     20 int nxt[MAXN<<1],fst[MAXN],n,to[MAXN<<1],Val[MAXN<<1],Cnt,val[MAXN];
     21 int cnt[MAXN],bl[MAXN],fa[MAXN],dep[MAXN],hsh[MAXN];
     22 struct data {int l,r,mn,mx,sum;bool tag;}tr[MAXN<<2];
     23 void add(int u,int v,int w) {nxt[++Cnt]=fst[u],fst[u]=Cnt,to[Cnt]=v,Val[Cnt]=w;}
     24 void dfs(int x)
     25 {
     26     cnt[x]=1;
     27     for(int i=fst[x];i;i=nxt[i])
     28     {
     29         if(to[i]==fa[x]) continue;
     30         val[to[i]]=Val[i],fa[to[i]]=x,dep[to[i]]=dep[x]+1;
     31         dfs(to[i]);
     32         cnt[x]+=cnt[to[i]];
     33     }
     34 }
     35 void Dfs(int x,int anc)
     36 {
     37     int hvs=0;hsh[x]=++Cnt,bl[x]=anc;
     38     for(int i=fst[x];i;i=nxt[i])
     39         if(to[i]!=fa[x]&&cnt[to[i]]>cnt[hvs]) hvs=to[i];
     40     if(!hvs) return ;
     41     Dfs(hvs,anc);
     42     for(int i=fst[x];i;i=nxt[i])
     43         if(to[i]!=fa[x]&&to[i]!=hvs) Dfs(to[i],to[i]);
     44 }
     45 void build(int k,int l,int r)
     46 {
     47     tr[k].l=l,tr[k].r=r,tr[k].tag=0;
     48     if(l==r) return ;
     49     int mid=(l+r)>>1;
     50     build(k<<1,l,mid);
     51     build(k<<1|1,mid+1,r);
     52 }
     53 void pushdown(int k)
     54 {
     55     tr[k<<1].tag^=1,tr[k<<1|1].tag^=1;
     56     swap(tr[k<<1].mx,tr[k<<1].mn);swap(tr[k<<1|1].mx,tr[k<<1|1].mn);
     57     tr[k<<1].mx=-tr[k<<1].mx,tr[k<<1].mn=-tr[k<<1].mn,tr[k<<1].sum=-tr[k<<1].sum;
     58     tr[k<<1|1].mx=-tr[k<<1|1].mx,tr[k<<1|1].mn=-tr[k<<1|1].mn,tr[k<<1|1].sum=-tr[k<<1|1].sum;
     59     tr[k].tag=0;
     60 }
     61 void upd(int k,int pos,int x)
     62 {
     63     int l=tr[k].l,r=tr[k].r;
     64     if(l==r) {tr[k].sum=tr[k].mn=tr[k].mx=x;return ;}
     65     if(tr[k].tag) pushdown(k);
     66     int mid=(l+r)>>1;
     67     if(mid>=pos) upd(k<<1,pos,x);
     68     else upd(k<<1|1,pos,x);
     69     tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
     70     tr[k].mx=max(tr[k<<1].mx,tr[k<<1|1].mx);
     71     tr[k].mn=min(tr[k<<1].mn,tr[k<<1|1].mn);
     72 }
     73 void Upd(int k,int a,int b)
     74 {
     75     if(a>b) return ;
     76     int l=tr[k].l,r=tr[k].r;
     77     if(l==a&&r==b) 
     78     {
     79         tr[k].sum=-tr[k].sum;
     80         swap(tr[k].mx,tr[k].mn);
     81         tr[k].mx=-tr[k].mx,tr[k].mn=-tr[k].mn,tr[k].tag^=1;return ;
     82     }
     83     if(tr[k].tag) pushdown(k);
     84     int mid=(l+r)>>1;
     85     if(mid>=b) Upd(k<<1,a,b);
     86     else if(mid<a) Upd(k<<1|1,a,b);
     87     else {Upd(k<<1,a,mid);Upd(k<<1|1,mid+1,b);}
     88     tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
     89     tr[k].mx=max(tr[k<<1].mx,tr[k<<1|1].mx);
     90     tr[k].mn=min(tr[k<<1].mn,tr[k<<1|1].mn);
     91 }
     92 int query(int k,int a,int b,int x)
     93 {
     94     if(a>b&&x>0) return -inf;
     95     if(a>b&&x<0) return inf;
     96     if(a>b&&x==0) return 0;
     97     int l=tr[k].l,r=tr[k].r;
     98     if(a==l&&b==r)
     99     {
    100         if(x>0) return tr[k].mx;
    101         if(x<0) return tr[k].mn;
    102         if(x==0) return tr[k].sum;
    103     }
    104     if(tr[k].tag) pushdown(k);
    105     int mid=(l+r)>>1;
    106     if(mid>=b) return query(k<<1,a,b,x);
    107     else if(mid<a) return query(k<<1|1,a,b,x);
    108     else
    109     {
    110         if(x>0) return max(query(k<<1,a,mid,x),query(k<<1|1,mid+1,b,x));
    111         if(x<0) return min(query(k<<1,a,mid,x),query(k<<1|1,mid+1,b,x));
    112         if(x==0) return query(k<<1,a,mid,x)+query(k<<1|1,mid+1,b,x);
    113     }
    114 }
    115 int main()
    116 {
    117     n=read();int a,b,c;
    118     for(int i=1;i<n;i++) {a=read()+1,b=read()+1,c=read();add(a,b,c);add(b,a,c);}
    119     dep[1]=1,fa[1]=1;
    120     dfs(1);Cnt=0;
    121     Dfs(1,1);
    122     build(1,1,n);
    123     for(int i=1;i<=n;i++) upd(1,hsh[i],val[i]);
    124     int T=read(),t,res;char ch[7];
    125     while(T--)
    126     {
    127         scanf("%s",ch);a=read()+1,b=read()+1;
    128         if(ch[0]=='C')
    129         {
    130             a--;
    131             t=a<<1;
    132             if(fa[to[t]]==to[t-1]) c=to[t];
    133             else c=to[t-1];
    134             upd(1,hsh[c],b-1);
    135         }
    136         else if(ch[0]=='N')
    137         {
    138             while(bl[a]!=bl[b])
    139             {
    140                 if(dep[bl[a]]<dep[bl[b]]) swap(a,b);
    141                 Upd(1,hsh[bl[a]],hsh[a]);
    142                 a=fa[bl[a]];
    143             }
    144             Upd(1,min(hsh[a],hsh[b])+1,max(hsh[a],hsh[b]));
    145         }
    146         else
    147         {
    148             if(ch[0]=='S') t=0;
    149             else if(ch[1]=='A') t=1;
    150             else if(ch[1]=='I') t=-1;
    151             if(t<0) res=inf;
    152             if(t>0) res=-inf;
    153             if(t==0)res=0;
    154             while(bl[a]!=bl[b])
    155             {
    156                 if(dep[bl[a]]<dep[bl[b]]) swap(a,b);
    157                 if(t==0) res+=query(1,hsh[bl[a]],hsh[a],t);
    158                 if(t<0) res=min(res,query(1,hsh[bl[a]],hsh[a],t));
    159                 if(t>0) res=max(res,query(1,hsh[bl[a]],hsh[a],t));
    160                 a=fa[bl[a]];
    161             }
    162             if(t==0) res+=query(1,min(hsh[a],hsh[b])+1,max(hsh[a],hsh[b]),t);
    163             if(t<0) res=min(res,query(1,min(hsh[a],hsh[b])+1,max(hsh[a],hsh[b]),t));
    164             if(t>0) res=max(res,query(1,min(hsh[a],hsh[b])+1,max(hsh[a],hsh[b]),t));
    165             printf("%d
    ",res);
    166         }
    167     }
    168 }
    View Code

    没看题解调这道题调了5h

  • 相关阅读:
    获得树形json串
    淘宝分布式 key/value 存储引擎Tair安装部署过程及Javaclient測试一例
    ARC下dealloc过程及.cxx_destruct的探究
    连类比事-category和extension
    category和关联对象
    静态构造函数c# 静态块java initallize oc
    + (void)initialize vs 静态构造方法
    Servlet中文乱码原因 解决 Get 和 Post 和客户端
    double int 类型的区别
    待解决问题 oc
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/7988435.html
Copyright © 2020-2023  润新知