poj3237 Tree [树链剖分]

来源:互联网 发布:linux下无线网卡驱动 编辑:程序博客网 时间:2024/06/10 13:05

这个题是spoj的改版

是在原来的题意上增加了区间取反操作

所以只需要在spoj375的基础上再线段树上增加一个取反标志

同时在维护一个区间最小值

因为在区间取反了以后 区间的最大值就是区间原来的最小值

嗯 就这样就可以了


#include <iostream>#include <stdio.h>#include <string.h>using namespace std;struct Node{int next,num;}edge[20001];struct Node1{int x,y,v;}a[10001];int cnt;int dep[10001],num[10001],fa[10001],head[10001],siz[10001],son[10001],topfa[10001],id[10001];void add(int x,int y){edge[cnt].num=y;edge[cnt].next=head[x];head[x]=cnt++;edge[cnt].num=x;edge[cnt].next=head[y];head[y]=cnt++;}void dfs1(int x,int f,int d){dep[x]=d;fa[x]=f;siz[x]=1;son[x]=0;for(int i=head[x];i!=-1;i=edge[i].next){int v=edge[i].num;if(v==f) continue;dfs1(v,x,d+1);siz[x]+=siz[v];if(siz[son[x]]<siz[v]) son[x]=v;}}int nu;void dfs2(int x,int f){topfa[x]=f;id[x]=++nu;if(son[x]) dfs2(son[x],f);for(int i=head[x];i!=-1;i=edge[i].next){int v=edge[i].num;if(v==fa[x]||v==son[x]) continue;dfs2(v,v);}}struct Tree{int l,r,flag,min,max;}t[40001];int max(int x,int y){if(x<y) return y;return x;}int min(int x,int y){if(x>y) return y;return x;}void swap(int &x,int &y){int c=x;x=y;y=c;}void build(int l,int r,int x){//cout << l << " " << r << " " << x << endl;int ls=x<<1,rs=ls|1;t[x].l=l,t[x].r=r;t[x].flag=0;if(l==r) {t[x].max=num[l];t[x].min=num[l];return;}int mid=(l+r)>>1;build(l,mid,ls);build(mid+1,r,rs);t[x].max=max(t[ls].max,t[rs].max);t[x].min=min(t[ls].min,t[rs].min);}void updata(int x,int ls,int rs){if(t[ls].flag){t[x].max=-t[ls].min;t[x].min=-t[ls].max;}else{t[x].max=t[ls].max;t[x].min=t[ls].min;}if(t[rs].flag){t[x].max=max(t[x].max,-t[rs].min);t[x].min=min(t[x].min,-t[rs].max);}else{t[x].max=max(t[x].max,t[rs].max);t[x].min=min(t[x].min,t[rs].min);}}void change(int l,int v,int x){int ls=x<<1,rs=ls|1;if(l==t[x].l&&l==t[x].r) { t[x].flag=0;t[x].max=v;t[x].min=v; return;}if(t[x].flag) {t[ls].flag^=1;t[rs].flag^=1;t[x].flag=0;}int mid=(t[x].l+t[x].r)>>1;if(l<=mid) change(l,v,ls);if(l>mid) change(l,v,rs);updata(x,ls,rs);}void change_flag(int l,int r,int x){int ls=x<<1,rs=ls|1;if(l==t[x].l&&r==t[x].r) {t[x].flag^=1;return;}int mid=(t[x].l+t[x].r)>>1;if(t[x].flag) {t[ls].flag^=1;t[rs].flag^=1;t[x].flag=0;}if(r<=mid) change_flag(l,r,ls);else if(l>mid) change_flag(l,r,rs);else{change_flag(l,mid,ls);change_flag(mid+1,r,rs);}updata(x,ls,rs);}int tree_query(int l,int r,int x){ int ls=x<<1,rs=ls|1; if(l==t[x].l&&r==t[x].r){ if(t[x].flag) return -t[x].min;else return t[x].max; }int mid=(t[x].l+t[x].r)>>1;int ans;if(t[x].flag) {t[ls].flag^=1;t[rs].flag^=1;t[x].flag=0;}if(mid>=r) ans=tree_query(l,r,ls);else if(mid<l) ans=tree_query(l,r,rs);else ans=max(tree_query(l,mid,ls),tree_query(mid+1,r,rs));updata(x,ls,rs);return ans;}void flag(int x,int y){if(x==y) return;if(dep[x]>dep[y]) swap(x,y);if(topfa[x]==topfa[y]) {change_flag(id[x]+1,id[y],1);return;}if(dep[topfa[y]]>dep[topfa[x]]) swap(x,y);change_flag(id[topfa[x]],id[x],1);flag(fa[topfa[x]],y);}int query(int x,int y){if(x==y)  return -1234567890;if(dep[x]>dep[y]) swap(x,y);if(topfa[x]==topfa[y]) return tree_query(id[x]+1,id[y],1);if(dep[topfa[x]]<dep[topfa[y]]) swap(x,y);return max(tree_query(id[topfa[x]],id[x],1),query(fa[topfa[x]],y));}int main(){int T,n;scanf("%d",&T);while(T--){nu=0;cnt=0;memset(head,-1,sizeof(head));scanf("%d",&n);for(int i=1;i<n;i++){scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].v);add(a[i].x,a[i].y);}dfs1(1,0,1);dfs2(1,1);for(int i=1;i<n;i++){if(fa[a[i].y]==a[i].x) swap(a[i].x,a[i].y);num[id[a[i].x]]=a[i].v;}build(1,n,1);char s[10];int x,y;while(1){scanf("%s",&s);if(s[0]=='D') break;scanf("%d%d",&x,&y);if(s[0]=='C'){change(id[a[x].x],y,1);}else if(s[0]=='N'){flag(x,y);}else printf("%d\n",query(x,y));//cout << s[0] << endl;}}}


0 0
原创粉丝点击