树链剖分+线段树 POJ3237 权值在边 模板

#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int maxn=100010;
struct Edge{
     int to;
     int next;
}edge[maxn*2];
int head[maxn],tot;
int top[maxn];//top[v]表示v所在的重链的顶端节点
int fa[maxn];//父亲节点
int deep[maxn];//深度
int num[maxn];//num[v]表示以v为根的子树的节点数
int p[maxn];//p[v]表示v与其父亲节点的连边在线段树中的位置
int fp[maxn];//和p数组相反
int son[maxn];//重儿子
int pos;
int e[maxn][3];
void init()
{
     tot=0;
     memset(head,-1,sizeof(head));
     pos=0;
     memset(son,-1,sizeof(son));
}
void add(int u,int v)
{
     edge[tot].to=v;
     edge[tot].next=head[u];
     head[u]=tot++;
}
void dfs1(int u,int father,int dep)//第一遍dfs求出fa,deep,num,son
{
     deep[u]=dep;
     fa[u]=father;
     num[u]=1;
     for(int i=head[u];i!=-1;i=edge[i].next)
     {
          int v=edge[i].to;
          if(v!=father)
          {
               dfs1(v,u,dep+1);
               num[u]+=num[v];
               if(son[u]==-1||num[son[u]]mid)
          return query(i*2+1,l,r);
     else
     {
          return max(query(i*2,l,mid),query(i*2+1,mid+1,r));
     }
     pushup(i);
}
int findmax(int u,int v)//查询u->v边的最大值
{
     int f1=top[u];
     int f2=top[v];
     int tmp=-100000000;
     while(f1!=f2)
     {
          if(deep[f1]deep[v])
          swap(u,v);
     return max(tmp,query(1,p[son[u]],p[v]));
}
void Negate1(int i,int l,int r)// 更新线段树的区间[l,r]取反
{
     if(q[i].l==l&&q[i].r==r)
     {
          q[i].maxx=-q[i].maxx;
          q[i].minn=-q[i].minn;
          swap(q[i].maxx,q[i].minn);
          q[i].nege^=1;
          return;
     }
     pushdown(i);
     int mid=(q[i].l+q[i].r)/2;
     if(r<=mid)
          Negate1(i*2,l,r);
     else if(l>mid)
          Negate1(i*2+1,l,r);
     else
     {
          Negate1(i*2,l,mid);
          Negate1(i*2+1,mid+1,r);
     }
     pushup(i);
}
void Negate(int u,int v)//把u-v路径上的边的值都设置为val
{
     int f1=top[u];
     int f2=top[v];
     while(f1!=f2)
     {
          if(deep[f1]deep[v])
          swap(u,v);
     return Negate1(1,p[son[u]],p[v]);
}
int main(void)
{
     int i,j,k,t,n;
     scanf("%d",&t);
     while(t--)
     {
          init();
          scanf("%d",&n);
          for(i=0;ideep[e[i][1]])
                    swap(e[i][0],e[i][1]);
               update(1,p[e[i][1]],e[i][2]);
          }
          char op[10];
          int x,y;
          while(scanf("%s",op)!=EOF)
          {
               if(op[0]=='D')
                    break;
               scanf("%d%d",&x,&y);
               if(op[0]=='Q')
                    printf("%d\n",findmax(x,y));//查询x->y路径上边权的最大值
               else if(op[0]=='C')
                    update(1,p[e[x-1][1]],y);//改变第x条边的值为y
               else
                    Negate(x,y);
          }
     }
     return 0;
}

你可能感兴趣的:(树链剖分+线段树 POJ3237 权值在边 模板)