记录编号 119062 评测结果 AAAAAAAAAW
题目名称 [SPOJ 375] 难存的情缘 最终得分 90
用户昵称 GravatarHouJikan 是否通过 未通过
代码语言 C++ 运行时间 0.313 s
提交时间 2014-09-10 21:51:01 内存使用 0.92 MiB
显示代码纯文本
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <list>
#include <vector>
#include <ctime>
#include <functional>
#define pritnf printf
#define scafn scanf
#define For(i,j,k) for(int i=(j);i<=(k);(i)++)
using namespace std;
typedef long long LL;
typedef unsigned int Uint; 
const int INF=0x7ffffff;
//==============struct declaration==============
struct edges
{
  int s,e,t;
  int no;
  edges (int s,int e,int t,int no):s(s),e(e),t(t),no(no){};
};
//==============var declaration=================
#define y1 y
int minv[10000*3],maxv[10000*3],son[10001],top[10001],siz[10001],dep[10001], fa[10001],w[10001];
bool vis[10001];
bool negated[10000*3];
int t,n,y1,y2,totw,maxdepth,k,v;
vector <edges> Edge[10001];
vector <edges> edgelist;
//==============function declaration============
void buildtree();
void update(int o,int l,int r);//将编号为k的节点设定为v,当前节点编号为o,范围[l,r] 
void maintain(int o,int l,int r);//更新o节点信息 
void dfs_1(int o);//求出fa dep siz son 
void dfs_2(int o);//求出top w以及各条边在线段树中的编号 
void Set_Negate(int s,int e);//将s->e路径上的所有边变为负值 
void Negate(int o,int l,int r);
int Get_Max_Value(int s,int e);//求出s->e路径上的边的最大值 
void Set_Value(int rank,int value);//将ranklist中第K条边权值设置为value 
int query(int o,int l,int r,bool neg);//
//==============main code=======================
int main()
{  
  string FileName="qtree";//程序名 
  string FloderName="COGS";//文件夹名 
  freopen((FileName+".in").c_str(),"r",stdin);
  freopen((FileName+".out").c_str(),"w",stdout);
#ifdef DEBUG  
  system(("cp C:\\Users\\Administrator\\Desktop\\"+FloderName+"\\standard.cpp C:\\Users\\Administrator\\Desktop\\"+FloderName+"\\submit.txt").c_str());
  clock_t Start_Time=clock();
#endif    
  scanf("%d",&n);
  For(i,1,n)
    Edge[i].clear();
  For(i,1,n*3)
  {
    maxv[i]=-INF;
    minv[i]=INF;
  }
  edgelist.clear();
  int s,e,t;
  For(i,1,n-1)
  {     
    scanf("%d%d%d",&s,&e,&t);
    Edge[s].push_back(edges(s,e,t,i-1));
    Edge[e].push_back(edges(e,s,t,i-1));
    edgelist.push_back(edges(s,e,t,i-1));
    //Edge中的no记录的是该边在edgelist中的位置
    //edgelist中的no记录的是该边在线段树中的位置 
  }
  buildtree();
  char cmd[10];
  while (scanf(" %s",cmd)!=EOF&&cmd[0]!='D')
  {
    if (cmd[0]=='Q')
    {
        scanf("%d%d",&s,&e);
        printf("%d\n",Get_Max_Value(s,e));
    }
    else if (cmd[0]=='C')
    {
      scanf("%d%d",&k,&v);
      Set_Value(k-1,v);
    }
    else 
      pritnf("Init Error!\n");
  }
#ifdef DEBUG  
  clock_t End_Time=clock();
  cout<<endl<<endl<<"Time Used: "<<End_Time-Start_Time<<endl;
#endif    
  return 0;
}
//================fuction code====================
void buildtree()
{
   memset(vis,false,sizeof(vis));
   totw=0; 
   dep[1]=1;
   fa[1]=top[1]=1;
   dfs_1(1);
   memset(vis,false,sizeof(vis));
   dfs_2(1);
   For(i,0,n-2)
   {
     k=edgelist[i].no;
     v=edgelist[i].t;
     update(1,1,n);
   }
}
void dfs_1(int o)//求出fa dep siz son
{
  int m=Edge[o].size()-1;
  int size=1,maxsonsize=0;
  vis[o]=true;
  For(i,0,m)
  {
    edges x=Edge[o][i];
    if (vis[x.e]) 
      continue; 
    dep[x.e]=dep[o]+1;
    fa[x.e]=o;
    dfs_1(x.e);
    if (siz[x.e]>maxsonsize)
    {
      maxsonsize=siz[x.e];                        
      son[o]=x.e;
      
    }
    size+=siz[x.e];
  }
  siz[o]=size;
  return ;
}
void dfs_2(int o)//求出top w以及各条边在线段树中的编号 
{
  vis[o]=true;
  int m=Edge[o].size()-1;
  For(i,0,m)
    if (Edge[o][i].e==son[o])
    {
      edgelist[Edge[o][i].no].no=++totw;
      top[son[o]]=top[o];
      w[son[o]]=totw;
      dfs_2(Edge[o][i].e);
      break;
    }
  For(i,0,m)
  {
    edges x=Edge[o][i];
    if (vis[x.e]||x.e==son[o]) continue;
    edgelist[x.no].no=++totw;
    top[x.e]=x.e;
    w[x.e]=totw;
    dfs_2(x.e);
  }
} 
void update(int o,int l,int r)
{
  int lc=o*2;
  int rc=o*2+1;
  int m=(l+r)/2;
  if (l==r)
  {
    maxv[o]=minv[o]=v;
    return ;
  }
  if (k<=m)
    update(lc,l,m);
  else
    update(rc,m+1,r);
  maintain(o,l,r);
}
void maintain(int o,int l,int r)
{
  int lc=o*2;
  int rc=o*2+1;
  if (l!=r)
  {
    maxv[o]=max(maxv[lc],maxv[rc]);
    minv[o]=min(minv[lc],minv[rc]);
  }
  return ;
}
void Negate(int o,int l,int r)
{
  int lc=o*2;
  int rc=o*2+1;
  int m=(l+r)/2;
  if (y1<=l&&r<=y2)
  {
    negated[o]=!negated[o];
    int temp=maxv[o];
    maxv[o]=-minv[o];
    minv[o]=-temp;
    return ;
  }
  if (negated[o])
  {
    negated[o]=false;
    negated[lc]=!negated[lc];
    negated[rc]=!negated[rc];
    int tmp=minv[lc];
    minv[lc]=-maxv[lc];
    maxv[lc]=-tmp;
    tmp=minv[rc];
    minv[rc]=-maxv[rc];
    maxv[rc]=-tmp;
  }
  if (y1<=m)
    Negate(lc,l,m);
  if (m<y2)
    Negate(rc,m+1,r);
  return ;
  maintain(o,l,r);
}
void Set_Negate(int s,int e)
{
  int u=s,v=e;
  int f1=top[u],f2=top[v];
  while (f1!=f2)
  {
    if (dep[f1]<dep[f2])
      swap(f1,f2),swap(u,v);
    y1=w[f1];y2=w[u];
    Negate(1,1,n) ;
    u=fa[f1];f1=top[u];
  }
  if (u==v)
    return;
  if (dep[u]<dep[v])
    swap(u,v);
  y1=w[son[v]];y2=w[u];
  Negate(1,1,n);
  return ;
}
int Get_Max_Value(int s,int e)
{
  int maxvalue=-INF;
  int u=s,v=e;
  int f1=top[u],f2=top[v];
  while (f1!=f2)
  {
    if (dep[f1]<dep[f2])//f1在上面,将f2向上移动.. 
      swap(f1,f2),swap(u,v);
    y1=w[f1];y2=w[u];
    maxvalue=max(query(1,1,n,false),maxvalue); 
    u=fa[f1];f1=top[u];
  }
  if (u==v) return maxvalue;
  if (dep[u]<dep[v])
    swap(u,v);
  y1=w[son[v]];y2=w[u];
  int temp=query(1,1,n,false);
  if (temp>maxvalue)
    maxvalue=temp;
  return maxvalue;
}
int query(int o,int l,int r,bool neg)
{
  int lc=o*2 ;
  int rc=o*2+1;
  int m=(l+r)/2;
  if (y1<=l&&r<=y2)
  {
    if (neg)
      return -minv[o];
    else
      return maxv[o];
  }
  int maxvalue=-INF;
  if (y1<=m)
    maxvalue=max(query(lc,l,m,neg^negated[o]),maxvalue);
  if (m<y2)
    maxvalue=max(query(rc,m+1,r,neg^negated[o]),maxvalue);
  return maxvalue;
}
void Set_Value(int rank,int value)
{
  k=edgelist[rank].no;
  v=value;
  update(1,1,n);
}