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\n",findsum(l,r));
209         else if(opt[1]=='A') printf("%d\n",findmx(l,r));
210         else printf("%d\n",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\n" , 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( '\n' );
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 << ' ' << "\n";
41     build_tree();
42     cout << m << "\n";
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),输出答案。

posted @ 2015-08-29 14:04  ChenThree  阅读(218)  评论(0编辑  收藏  举报