zoukankan      html  css  js  c++  java
  • bzoj2157

    链剖。。

      1 #include<bits/stdc++.h>
      2 #define lowbit(a) ((a)&(-(a)))
      3 #define l(a) ((a)<<1)
      4 #define r(a) ((a)<<1|1)
      5 #define clr(a,x) memset(a,x,sizeof(a))
      6 #define rep(i,l,r) for(int i=l;i<(r);i++)
      7 #define Rep(i,k) rep(i,0,e[k].size())
      8 typedef long long ll;
      9 using namespace std;
     10 int read()
     11 {
     12     char c=getchar();
     13     int ans=0,f=1;
     14     while(!isdigit(c)){
     15         if(c=='-') f=-1;
     16         c=getchar();
     17     }
     18     while(isdigit(c)){
     19         ans=ans*10+c-'0';
     20         c=getchar();
     21     }
     22     return ans*f;
     23 }
     24 const int maxn=20009,inf=0x3fffffff;
     25 int n,m,dfstime=0,c[maxn],u[maxn],v[maxn],d[maxn],w[maxn],id[maxn],idr[maxn],dep[maxn],top[maxn],fa[maxn],son[maxn],size[maxn];
     26 vector<int>e[maxn];
     27 void dfs(int k){
     28     size[k]=1;
     29     Rep(i,k){
     30         int to=e[k][i];
     31         if(to==fa[k]) continue;
     32         fa[to]=k;
     33         dep[to]=dep[k]+1;
     34         dfs(to);
     35         size[k]+=size[to];
     36         if(!son[k]||size[son[k]]<size[to]) son[k]=to;
     37     }
     38 }
     39 int Top=0;
     40 void Dfs(int k){
     41     top[k]=Top;
     42     id[k]=++dfstime;
     43     idr[id[k]]=k;
     44     if(son[k]) Dfs(son[k]);
     45     Rep(i,k){
     46         int to=e[k][i];
     47         if(id[to]) continue;
     48         Dfs(Top=to);
     49     }
     50 }
     51 struct node{
     52     int l,r,mx,mn;
     53     ll sum;
     54     bool rev;
     55 };
     56 node x[maxn<<2];
     57 void maintain(int k){
     58     x[k].sum=x[l(k)].sum+x[r(k)].sum;
     59     x[k].mx=max(x[l(k)].mx,x[r(k)].mx);
     60     x[k].mn=min(x[l(k)].mn,x[r(k)].mn);
     61 }
     62 void pushdown(int k){
     63     if(x[k].rev&&x[k].l!=x[k].r){
     64         x[l(k)].rev^=1;x[r(k)].rev^=1;
     65         x[l(k)].sum=-x[l(k)].sum;x[r(k)].sum=-x[r(k)].sum;
     66         x[l(k)].mx=-x[l(k)].mx;x[r(k)].mx=-x[r(k)].mx;
     67         x[l(k)].mn=-x[l(k)].mn;x[r(k)].mn=-x[r(k)].mn;
     68         swap(x[l(k)].mx,x[l(k)].mn);swap(x[r(k)].mx,x[r(k)].mn);
     69     }
     70     x[k].rev=0;
     71 }
     72 void build(int k,int l,int r){
     73     x[k].l=l;x[k].r=r;x[k].rev=0;
     74     if(l==r){
     75         if(l!=1) x[k].sum=x[k].mx=x[k].mn=w[idr[l]];
     76         else{
     77             x[k].sum=0;x[k].mx=-inf;x[k].mn=inf;
     78         }
     79         return;
     80     }
     81     int mid=(l+r)>>1;
     82     build(l(k),l,mid);
     83     build(r(k),mid+1,r);
     84     maintain(k);
     85 }
     86 void update(int k,int p,int t){
     87     pushdown(k);
     88     if(x[k].l==x[k].r){
     89         x[k].sum=x[k].mn=x[k].mx=t;
     90         return;
     91     }
     92     int mid=(x[k].l+x[k].r)>>1;
     93     update(p<=mid?l(k):r(k),p,t);
     94     maintain(k);
     95 }
     96 void modify(int k,int l,int r){
     97     pushdown(k);
     98     if(x[k].l==l&&x[k].r==r){
     99         x[k].rev=1;
    100         x[k].sum=-x[k].sum;
    101         x[k].mx=-x[k].mx;
    102         x[k].mn=-x[k].mn;
    103         swap(x[k].mx,x[k].mn);
    104         return;
    105     }
    106     int mid=(x[k].l+x[k].r)>>1;
    107     if(r<=mid) modify(l(k),l,r);
    108     else if(l>mid) modify(r(k),l,r);
    109     else{
    110         modify(l(k),l,mid);
    111         modify(r(k),mid+1,r);
    112     }
    113     maintain(k);
    114 }
    115 ll asksum(int k,int l,int r){
    116     pushdown(k);
    117     if(x[k].l==l&&x[k].r==r) return x[k].sum;
    118     int mid=(x[k].l+x[k].r)>>1;
    119     if(r<=mid) return asksum(l(k),l,r);
    120     if(l>mid) return asksum(r(k),l,r);
    121     return asksum(l(k),l,mid)+asksum(r(k),mid+1,r);
    122 }
    123 int askmx(int k,int l,int r){
    124     pushdown(k);
    125     if(x[k].l==l&&x[k].r==r) return x[k].mx;
    126     int mid=(x[k].l+x[k].r)>>1;
    127     if(r<=mid) return askmx(l(k),l,r);
    128     if(l>mid) return askmx(r(k),l,r);
    129     return max(askmx(l(k),l,mid),askmx(r(k),mid+1,r));
    130 }
    131 int askmn(int k,int l,int r){
    132     pushdown(k);
    133     if(x[k].l==l&&x[k].r==r) return x[k].mn;
    134     int mid=(x[k].l+x[k].r)>>1;
    135     if(r<=mid) return askmn(l(k),l,r);
    136     if(l>mid) return askmn(r(k),l,r);
    137     return min(askmn(l(k),l,mid),askmn(r(k),mid+1,r));
    138 }
    139 ll findsum(int U,int V){
    140     ll ans=0;
    141     while(top[U]!=top[V]){
    142         if(dep[top[U]]<dep[top[V]]) swap(U,V);
    143         ans+=asksum(1,id[top[U]],id[U]);
    144         U=fa[top[U]];
    145     }
    146     if(U==V) return ans;
    147     if(dep[U]>dep[V]) swap(U,V);
    148     ans+=asksum(1,id[U]+1,id[V]);
    149     return ans;
    150 }
    151 int findmx(int U,int V){
    152     int ans=-inf;
    153     while(top[U]!=top[V]){
    154         if(dep[top[U]]<dep[top[V]]) swap(U,V);
    155         ans=max(ans,askmx(1,id[top[U]],id[U]));
    156         U=fa[top[U]];
    157     }
    158     if(U==V) return ans;
    159     if(dep[U]>dep[V]) swap(U,V);
    160     ans=max(ans,askmx(1,id[U]+1,id[V]));
    161     return ans;
    162 }
    163 int findmn(int U,int V){
    164     int ans=inf;
    165     while(top[U]!=top[V]){
    166         if(dep[top[U]]<dep[top[V]]) swap(U,V);
    167         ans=min(ans,askmn(1,id[top[U]],id[U]));
    168         U=fa[top[U]];
    169     }
    170     if(U==V) return ans;
    171     if(dep[U]>dep[V]) swap(U,V);
    172     ans=min(ans,askmn(1,id[U]+1,id[V]));
    173     return ans;
    174 }
    175 void change(int U,int V){
    176     while(top[U]!=top[V]){
    177         if(dep[top[U]]<dep[top[V]]) swap(U,V);
    178         modify(1,id[top[U]],id[U]);
    179         U=fa[top[U]];
    180     }
    181     if(U==V) return;
    182     if(dep[U]>dep[V]) swap(U,V);
    183     modify(1,id[U]+1,id[V]);
    184 }
    185 int main()
    186 {    
    187     n=read();
    188     rep(i,1,n){
    189         u[i]=read();v[i]=read();d[i]=read();
    190         ++u[i];++v[i];
    191         e[u[i]].push_back(v[i]);
    192         e[v[i]].push_back(u[i]);
    193     }
    194     dfs(1);Dfs(1);
    195     rep(i,1,n){
    196         if(dep[u[i]]>dep[v[i]]) swap(u[i],v[i]);
    197         w[v[i]]=d[i];
    198     }
    199     build(1,1,n);
    200     m=read();
    201     while(m--){
    202         char opt[5];
    203         scanf(" %s",opt);
    204         int l=read(),r=read();
    205         ++l;++r;
    206         if(opt[0]=='C') update(1,id[v[l-1]],r-1);
    207         else if(opt[0]=='N') change(l,r);
    208         else if(opt[0]=='S') printf("%lld
    ",findsum(l,r));
    209         else if(opt[1]=='A') printf("%d
    ",findmx(l,r));
    210         else printf("%d
    ",findmn(l,r));
    211     }
    212     return 0;
    213 }
    View Code

    数据生成器

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cstdlib>
     4 #include<ctime>
     5 #include<iostream>
     6 #include<string>
     7 #include<algorithm>
     8  
     9 using namespace std;
    10  
    11 int n , m;
    12  
    13 void build_tree() {
    14     for( int i = 1 ; i < n ; ++i )
    15         printf( "%d %d %d
    " , i , rand() % i , rand() % 1001 * ( rand() & 1 ? -1 : 1 ) );
    16 }
    17  
    18 string s[ 5 ] = { "C" , "N" , "SUM" , "MAX" , "MIN" };
    19  
    20 void build_query() {
    21     while( m-- ) {
    22         int op = rand() % 5;
    23         cout << s[ op ] << ' ';
    24         if( ! op ) {
    25             printf( "%d %d" , rand() % ( n - 1 ) + 1 , rand() % 1001 * ( rand() & 1 ? -1 : 1 ) );
    26         } else {
    27             int u = rand() % n , v = rand() % n;
    28             while( v == u ) v =rand() % n;
    29             printf( "%d %d" , u , v );
    30         }
    31         putchar( '
    ' );
    32     }
    33 }
    34  
    35 int main() {
    36     freopen( "test.in" , "w", stdout );
    37     
    38     srand( time( NULL ) );
    39     n=5000,m=5000;
    40     cout << n << ' ' << "
    ";
    41     build_tree();
    42     cout << m << "
    ";
    43     build_query();
    44 
    45     return 0;
    46 }
    View Code

    2157: 旅游

    Time Limit: 10 Sec  Memory Limit: 259 MB
    Submit: 511  Solved: 282
    [Submit][Status][Discuss]

    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),输出答案。

  • 相关阅读:
    MFC绘制直角坐标系
    mfc画波形函数
    ciscn_2019_ne_5
    ciscn_2019_n_5
    [ZJCTF 2019]NiZhuanSiWei
    ciscn_2019_n_1
    pwn-100
    2014提高组笔试错题
    BZOJ3211: 花神游历各国
    主席树模板
  • 原文地址:https://www.cnblogs.com/chensiang/p/4769070.html
Copyright © 2011-2022 走看看