zoukankan      html  css  js  c++  java
  • BZOJ P2157 旅游

    题目大意:

    维护一棵树,每条边有边权,支持下列操作:
    1.修改某条边的边权
    2.将某条路经上的边权取反
    3.询问某条路经上的和
    4.询问某条路经上的最大值
    5.询问某条路经上的最小值

                                --by BZOJ;

    http://www.lydsy.com/JudgeOnline/problem.php?id=2157



    有关树链剖分的详解,见:树链剖分

    链剖模板,代码长了点,主要是线段树部分操作太多,注意可以把边权搞到点上;

    代码如下:

      1 #include<cstdio>
      2 #define INF 0x3fffffff
      3 using namespace std;
      4 struct ss{
      5     int to,next,dis;
      6 }x[40001];
      7 int first[20001],num;
      8 int size[20001];//子树和// 
      9 int hway[20001];//重边//
     10 int rank[20001];//点在line_tree中的位置//
     11 int rankl[20001];//边所对点在line_tree中的位置// 
     12 int dis[20001];//点权 //
     13 int top[20001];//重链顶 //
     14 int dep[20001];//深度 //
     15 int fa[20001];//父亲// 
     16 int a[20001];//line_tree的原line序列// 
     17 int ltre[100005];
     18 int max[100005];
     19 int min[100005];
     20 int lz[100005];
     21 int n,m,L,R,X,W;
     22 void swap(int&,int&);
     23 void build(int ,int ,int );
     24 void dfs_1(int );
     25 void dfs_2(int ,int );
     26 void up(int );
     27 void down(int ,int ,int );
     28 void builtre(int ,int ,int );
     29 void work(int );
     30 int wor_(int ,int );
     31 void chan1(int ,int ,int );
     32 void chan2(int ,int ,int );
     33 int sum(int ,int ,int );
     34 int Max(int ,int ,int );
     35 int Min(int ,int ,int );
     36 int main()
     37 {
     38     int i,j,k,l;
     39     char s[50];
     40     scanf("%d",&n);
     41     for(i=0;i<=n-1;i++)
     42         hway[i]=i;
     43     for(i=1;i<=n-1;i++){
     44         scanf("%d%d%d",&j,&k,&l);
     45         build(j,k,l);
     46         build(k,j,l);
     47     }
     48     dep[0]=1;
     49     dfs_1(0);
     50     num=0;
     51     dfs_2(0,0);
     52     num=0;
     53     builtre(1,n,1);
     54     scanf("%d",&m);
     55     for(i=1;i<=m;i++){
     56         scanf("%s",s);
     57         scanf("%d%d",&L,&R);
     58         if(s[1]!='')s[0]=s[1];
     59         if(s[0]=='C')X=rankl[L],W=R;
     60         switch (s[0]){
     61             case 'C':    chan1(1,n,1);break;//C
     62             case 'N':    work(2);break;//N
     63             case 'U':    work(3);break;//NUM
     64             case 'A':    work(4);break;//MAX
     65             case 'I':    work(5);break;//MIN
     66             }
     67     }
     68 }
     69 void swap(int &a,int &b){
     70     int i;
     71     i=a;a=b;b=i;
     72 }
     73 void build(int f,int t,int l){
     74     x[++num].next=first[f];
     75     x[num].dis=l;
     76     x[num].to=t;
     77     first[f]=num;
     78 }
     79 void dfs_1(int now){
     80     int j=first[now];
     81     while(j){
     82         if(!dep[x[j].to]){
     83             dis[x[j].to]=x[j].dis;
     84             dep[x[j].to]=dep[now]+1;
     85             fa[x[j].to]=now;
     86             dfs_1(x[j].to);
     87             size[now]+=size[x[j].to];
     88             if(hway[now]==now||size[x[j].to]>size[hway[now]])
     89                 hway[now]=x[j].to;
     90         }
     91         j=x[j].next;
     92     }
     93     size[now]++;
     94 }
     95 void dfs_2(int now,int to_nu){
     96     int j=first[now];
     97     top[now]=to_nu;
     98     rank[now]=++num;
     99     a[num]=now;
    100     if(hway[now]!=now)
    101         dfs_2(hway[now],to_nu);
    102     while(j){
    103         if(dep[x[j].to]>dep[now]&&x[j].to!=hway[now])
    104             rankl[(j+1)>>1]=num+1,dfs_2(x[j].to,x[j].to);
    105         if(x[j].to==hway[now])
    106             rankl[(j+1)>>1]=rank[hway[now]];
    107         j=x[j].next;
    108     }
    109 }
    110 void up(int nu){
    111     ltre[nu]=ltre[nu<<1]+ltre[nu<<1|1];
    112     max[nu]=max[nu<<1]>max[nu<<1|1]?max[nu<<1]:max[nu<<1|1];
    113     min[nu]=min[nu<<1]<min[nu<<1|1]?min[nu<<1]:min[nu<<1|1];
    114 }
    115 void down(int l,int r,int nu){
    116     if(!lz[nu])    return;
    117     lz[nu<<1]^=1;lz[nu<<1|1]^=1;
    118     swap(max[nu<<1],min[nu<<1]);
    119     max[nu<<1]=-max[nu<<1];    min[nu<<1]=-min[nu<<1];
    120     ltre[nu<<1]=-ltre[nu<<1];
    121     swap(max[nu<<1|1],min[nu<<1|1]);
    122     max[nu<<1|1]=-max[nu<<1|1];    min[nu<<1|1]=-min[nu<<1|1];
    123     ltre[nu<<1|1]=-ltre[nu<<1|1];
    124     lz[nu]=0;
    125 }
    126 void builtre(int l,int r,int nu){
    127     if(l==r){
    128         max[nu]=min[nu]=ltre[nu]=dis[a[++num]];
    129         if(a[num]==0){
    130             max[nu]=-INF;
    131             min[nu]=INF;
    132         }
    133         return;
    134     }
    135     int mid=(l+r)>>1;
    136     builtre(l,mid,nu<<1);
    137     builtre(mid+1,r,nu<<1|1);
    138     up(nu);
    139 }
    140 void work(int x){
    141     int ans=0;
    142     if(x==4)ans=-INF;
    143     if(x==5)ans=INF;
    144     int u=L,v=R;
    145         while(top[u]!=top[v]){
    146             if(dep[top[u]]<dep[top[v]])
    147                 L=rank[top[v]],R=rank[v],v=fa[top[v]];
    148             else
    149                 L=rank[top[u]],R=rank[u],u=fa[top[u]];
    150             ans=wor_(ans,x);
    151         }
    152         if(u!=v){
    153             if(dep[u]>dep[v])
    154                 swap(u,v);
    155             u=hway[u];
    156             L=rank[u];R=rank[v];
    157             ans=wor_(ans,x);
    158         }
    159     if(x>=3)
    160         printf("%d
    ",ans);
    161 }
    162 int wor_(int ans,int x){
    163     int i;
    164     if(x==2)
    165         chan2(1,n,1);
    166     if(x==3)
    167         ans+=sum(1,n,1);
    168     if(x==4){
    169         i=Max(1,n,1);ans=ans>i?ans:i;}
    170     if(x==5){
    171         i=Min(1,n,1);ans=ans<i?ans:i;}
    172     return ans;
    173 }
    174 void chan1(int l,int r,int nu){
    175     if(l==r){
    176         max[nu]=min[nu]=ltre[nu]=W ;
    177         return;
    178     }
    179     int mid=(l+r)>>1;
    180     down(l,r,nu);
    181     if(X<=mid)
    182         chan1(l,mid,nu<<1);
    183     if(X>mid)
    184         chan1(mid+1,r,nu<<1|1);
    185     up(nu);
    186 }
    187 void chan2(int l,int r,int nu){
    188     if(L<=l&&r<=R){
    189         swap(max[nu],min[nu]);
    190         max[nu]=-max[nu];
    191         min[nu]=-min[nu];
    192         ltre[nu]=-ltre[nu];
    193         lz[nu]^=1;
    194         return ;
    195     }
    196     down(l,r,nu);
    197     int mid=(l+r)>>1;
    198     if(L<=mid)
    199         chan2(l,mid,nu<<1);
    200     if(R>mid)
    201         chan2(mid+1,r,nu<<1|1);
    202     up(nu);
    203 }
    204 int sum(int l,int r,int nu){
    205     if(L<=l&&r<=R)
    206         return ltre[nu];
    207     down(l,r,nu);
    208     int mid=(l+r)>>1,re=0;
    209     if(L<=mid)
    210         re+=sum(l,mid,nu<<1);
    211     if(R>mid)
    212         re+=sum(mid+1,r,nu<<1|1);
    213     return re;
    214 }
    215 int Max(int l,int r,int nu){
    216     if(L<=l&&r<=R)
    217         return max[nu];
    218     down(l,r,nu);
    219     int mid=(l+r)>>1,lm=-INF,rm=-INF;
    220     if(L<=mid)
    221         lm=Max(l,mid,nu<<1);
    222     if(R>mid)
    223         rm=Max(mid+1,r,nu<<1|1);
    224     if(lm>=rm)
    225         return lm;
    226     return rm;
    227 }
    228 int Min(int l,int r,int nu){
    229     if(L<=l&&r<=R)
    230         return min[nu];
    231     down(l,r,nu);
    232     int mid=(l+r)>>1,lm=INF,rm=INF;
    233     if(L<=mid)
    234         lm=Min(l,mid,nu<<1);
    235     if(R>mid)
    236         rm=Min(mid+1,r,nu<<1|1);
    237     if(lm<=rm)
    238         return lm;
    239     return rm;
    240 }

    祝AC哟;

  • 相关阅读:
    魅族手机不能通过设置Style和Background展示透明Activity的解决方法
    [翻译]The dark side of AsyncTask
    Eclipse卡死在Building workspace和android library update解决方法
    影响Java代码性能的一些细节
    WebView通过loadDataWithBaseURL加载本地页面卡死
    [04] Android逐帧动画(一)
    [03] Android系统亮度调节
    iOS UIViewContentMode详解
    setObject:forKey:与setValue:forKey:的区别
    选择排序
  • 原文地址:https://www.cnblogs.com/nietzsche-oier/p/6385110.html
Copyright © 2011-2022 走看看