旅游(国家集训队)
来源:互联网 发布:html的js加减怎么做 编辑:程序博客网 时间:2024/05/03 03:53
题面
树链剖分,边权存到点上,注意边界处理
#include<iostream>#include<cstdio>#include<cstring>#define maxn 100005using namespace std;int n,m;struct edge{ int to,ne,w; }b[maxn];int k=0,head[maxn];struct tree{ int l,r,mx,mi,sum; }t[maxn*4];struct edge2{ int s,t,w; }a[maxn];int c[maxn];bool rev[maxn];int max(int x,int y){ return x >y ? x: y;}void swap(int &x,int &y){ int z=x;x=y;y=z; }inline int read(){ int x=0;char ch=getchar(); while(ch<'0'||ch>'9') ch=getchar(); while(ch>='0'&&ch<='9'){ x=x*10+ch-'0'; ch=getchar(); } return x; }void add(int u,int v,int w){ k++; b[k].to=v;b[k].ne=head[u];b[k].w=w;head[u]=k;}int fa[maxn],sz[maxn],son[maxn],d[maxn],top[maxn],id[maxn],pos[maxn];void dfs1(int x){ sz[x]=1; for(int i=head[x];i!=-1;i=b[i].ne) if(b[i].to!=fa[x]){ fa[b[i].to]=x; d[b[i].to]=d[x]+1; c[b[i].to]=b[i].w; dfs1(b[i].to); sz[x]+=sz[b[i].to]; if(son[x]==-1) son[x]=b[i].to; else if(sz[b[i].to]>sz[son[x]]) son[x]=b[i].to; }}int cnt=0;void dfs2(int x,int tp){ id[x]=++cnt; pos[cnt]=x; top[x]=tp; if(son[x]!=-1) dfs2(son[x],tp); for(int i=head[x];i!=-1;i=b[i].ne) if(b[i].to!=fa[x]&&b[i].to!=son[x]) dfs2(b[i].to,b[i].to);}struct Tree{ void swp(int &x,int &y) { int z=x; x=-y; y=-z; } void update(int z) { t[z].mx=max(t[z<<1].mx,t[z<<1|1].mx); t[z].mi=min(t[z<<1].mi,t[z<<1|1].mi); t[z].sum=t[z<<1].sum+t[z<<1|1].sum; } void build(int l,int r,int z) { t[z].l=l;t[z].r=r; if(l==r){ t[z].mx=t[z].mi=t[z].sum=c[pos[l]]; return ; } int mid=(l+r)>>1; build(l,mid,z<<1); build(mid+1,r,z<<1|1); update(z); } void xg(int x,int y,int z) { if(t[z].l==t[z].r){ t[z].mx=t[z].mi=t[z].sum=y; return ; } int mid=(t[z].l+t[z].r)>>1; if(x<=mid) xg(x,y,z<<1); else xg(x,y,z<<1|1); update(z); } void Rev(int x,int y,int z) { if(t[z].l==t[z].r){ t[z].mx*=-1;t[z].mi*=-1;t[z].sum*=-1; return ; } int mid=(t[z].l+t[z].r)>>1; if(x<=mid) Rev(x,y,z<<1); if(y>mid) Rev(x,y,z<<1|1); update(z); } int getsum(int x,int y,int z) { if(x<=t[z].l&&t[z].r<=y) return t[z].sum; int ans=0; int mid=(t[z].l+t[z].r)>>1; if(x<=mid) ans+=getsum(x,y,z<<1); if(y>mid) ans+=getsum(x,y,z<<1|1); return ans; } int getmax(int x,int y,int z) { if(x<=t[z].l&&t[z].r<=y) return t[z].mx; int ans=-0x7fffffff; int mid=(t[z].l+t[z].r)>>1; if(x<=mid) ans=max(ans,getmax(x,y,z<<1)); if(y>mid) ans=max(ans,getmax(x,y,z<<1|1)); return ans; } int getmin(int x,int y,int z) { if(x<=t[z].l&&t[z].r<=y) return t[z].mi; int ans=0x7fffffff; int mid=(t[z].l+t[z].r)>>1; if(x<=mid) ans=min(ans,getmin(x,y,z<<1)); if(y>mid) ans=min(ans,getmin(x,y,z<<1|1)); return ans; } }tr;void revc(int x,int y){ int fx=top[x],fy=top[y]; while(fx!=fy){ if(d[fx]<d[fy]) { swap(fx,fy); swap(x,y); } tr.Rev(id[fx],id[x],1); x=fa[fx]; fx=top[x]; } if(d[x]>d[y]) swap(x,y); tr.Rev(id[x]+1,id[y],1);}int getsum(int x,int y){ int fx=top[x],fy=top[y]; int ans=0; while(fx!=fy){ if(d[fx]<d[fy]) { swap(fx,fy); swap(x,y); } ans+=tr.getsum(id[fx],id[x],1); x=fa[fx]; fx=top[x]; } if(d[x]>d[y]) swap(x,y); ans+=tr.getsum(id[x]+1,id[y],1); return ans;}int getmax(int x,int y){ int fx=top[x],fy=top[y]; int ans=-0x7fffffff; while(fx!=fy){ if(d[fx]<d[fy]) { swap(fx,fy); swap(x,y); } ans=max(ans,tr.getmax(id[fx],id[x],1)); x=fa[fx]; fx=top[x]; } if(d[x]>d[y]) swap(x,y); ans=max(ans,tr.getmax(id[x]+1,id[y],1)); return ans;}int getmin(int x,int y){ int fx=top[x],fy=top[y]; int ans=0x7fffffff; while(fx!=fy){ if(d[fx]<d[fy]) { swap(fx,fy); swap(x,y); } ans=min(ans,tr.getmin(id[fx],id[x],1)); x=fa[fx]; fx=top[x]; } if(d[x]>d[y]) swap(x,y); ans=min(ans,tr.getmin(id[x]+1,id[y],1)); return ans;}int main(){ //freopen("in.txt","r",stdin); freopen("nt2011_travel.in","r",stdin); freopen("nt2011_travel.out","w",stdout); memset(head,-1,sizeof(head)); memset(son,-1,sizeof(son)); memset(fa,-1,sizeof(fa)); scanf("%d",&n); int x,y,z; char type[5]; for(int i=1;i<n;i++){ scanf("%d%d%d",&x,&y,&z); add(x,y,z); add(y,x,z); a[i].s=x;a[i].t=y; } dfs1(0); dfs2(0,0); tr.build(1,n+1,1); scanf("%d",&m); while(m--){ scanf("%s",type); scanf("%d%d",&x,&y); if(type[0]=='C'){ if(fa[a[x].s]==a[x].t) tr.xg(id[a[x].s],y,1); else tr.xg(id[a[x].t],y,1); } if(type[0]=='N') revc(x,y); if(type[0]=='S') printf("%d\n",getsum(x,y)); if(type[0]=='M'&&type[1]=='A') printf("%d\n",getmax(x,y)); if(type[0]=='M'&&type[1]=='I') printf("%d\n",getmin(x,y)); } return 0;}
阅读全文
1 0
- 旅游(国家集训队)
- [BZOJ2117][2010国家集训队]Crash的旅游计划
- acm国家集训队论文(1999-2009)
- 【国家集训队2011】数颜色 (莫队)
- [点分树 二分答案] BZOJ 2117 [2010国家集训队]Crash的旅游计划
- [BZOJ2117][[2010国家集训队]Crash的旅游计划][点分治+二分答案]
- 国家集训队论文分类
- 国家集训队论文集 ACM
- 国家集训队论文集题目
- 国家集训队论文分类
- 国家集训队论文分类
- NOI 国家集训队论文集
- 国家集训队论文分类
- 国家集训队论文分类
- NOI 国家集训队论文集
- NOI 国家集训队论文集
- NOI 国家集训队论文集
- 国家集训队论文
- Python中的metaclass
- Python里的String
- LinkedList 和 Array
- CPA会员充值PC加wap内置资源版源码
- 八大排序算法总结(超详细)
- 旅游(国家集训队)
- 一个银行账户5000块,两夫妻一个拿着 存折,一个拿着卡,开始取钱比赛,每次只能取一千块,要求不准出现线程安全问题。
- HDU 2048 数塔 (DP)
- HDU 2602 Bone Collector(01背包裸题)
- hdu 2546 饭卡-动态规划(基础中的基础题)
- 赌博-值得玩耍的棋牌 3
- git常见问题之git pull时Please specify which branch you want to merge with.
- FTP 主动模式与被动模式传输区别
- git常见问题之git pull origin master时fatal: refusing to merge unrelated histories