[国家集训队2011]旅游(宋方睿)

思路:

  树链剖分,边权转点权;

  线段树维护三个东西,sum,max,min;

  当一个区间变成相反数时,sum=-sum,max=-min,min=-max;

来,上代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; #define maxn 100005
#define ll long long
#define INF 0x7fffffff struct TreeNodeType {
ll l,r,mi,ma,sum,mid,flag;
};
struct TreeNodeType tree[maxn<<]; ll n,m,E[maxn<<],V[maxn<<],W[maxn<<],cnt;
ll deep[maxn],ps[maxn],pe[maxn],head[maxn],X,ty;
ll f[maxn],id[maxn],ds[maxn],size[maxn],top[maxn]; inline void in(ll &now)
{
ll if_z=;now=;
char Cget=getchar();
while(Cget>''||Cget<'')
{
if(Cget=='-') if_z=-;
Cget=getchar();
}
while(Cget>=''&&Cget<='')
{
now=now*+Cget-'';
Cget=getchar();
}
now*=if_z;
} inline void edge_add(ll u,ll v,ll w)
{
E[++cnt]=head[u],V[cnt]=v,W[cnt]=w,head[u]=cnt;
E[++cnt]=head[v],V[cnt]=u,W[cnt]=w,head[v]=cnt;
} void pre(ll now,ll fa)
{
f[now]=fa,size[now]=;
if(fa==-) deep[now]=;
else deep[now]=deep[fa]+;
for(ll i=head[now];i;i=E[i])
{
if(V[i]==fa) continue;
pre(V[i],now),size[now]+=size[V[i]];
}
} void dfs(ll now,ll chain,ll dis)
{
ll pos=n+,ww;
top[now]=chain,id[now]=++cnt,ds[cnt]=dis;
for(ll i=head[now];i;i=E[i])
{
if(V[i]==f[now]) continue;
if(size[V[i]]>size[pos]) pos=V[i],ww=W[i];
}
if(pos==n+) return ;
dfs(pos,chain,ww);
for(ll i=head[now];i;i=E[i])
{
if(V[i]==pos||V[i]==f[now]) continue;
dfs(V[i],V[i],W[i]);
}
} void tree_build(ll now,ll l,ll r)
{
tree[now].l=l,tree[now].r=r;
if(l==r)
{
tree[now].mi=ds[l];
tree[now].ma=ds[l];
tree[now].sum=ds[l];
return ;
}
tree[now].mid=l+r>>;
tree_build(now<<,l,tree[now].mid);
tree_build(now<<|,tree[now].mid+,r);
tree[now].sum=tree[now<<].sum+tree[now<<|].sum;
tree[now].ma=max(tree[now<<].ma,tree[now<<|].ma);
tree[now].mi=min(tree[now<<].mi,tree[now<<|].mi);
} inline void tree_down(ll now)
{
ll mii=tree[now<<].mi,maa=tree[now<<].ma;
tree[now<<].ma=-mii,tree[now<<].mi=-maa;
tree[now<<].sum=-tree[now<<].sum;
mii=tree[now<<|].mi,maa=tree[now<<|].ma;
tree[now<<|].mi=-maa,tree[now<<|].ma=-mii;
tree[now<<|].sum=-tree[now<<|].sum;
tree[now<<].flag=!tree[now<<].flag;
tree[now<<|].flag=!tree[now<<|].flag;
tree[now].flag=false;
} void tree_query(ll now,ll l,ll r)
{
if(tree[now].l==l&&tree[now].r==r)
{
if(ty==) X+=tree[now].sum;
else if(ty==) X=max(X,tree[now].ma);
else X=min(X,tree[now].mi);
return ;
}
if(tree[now].flag) tree_down(now);
if(l>tree[now].mid) tree_query(now<<|,l,r);
else if(r<=tree[now].mid) tree_query(now<<,l,r);
else tree_query(now<<,l,tree[now].mid),tree_query(now<<|,tree[now].mid+,r);
} void tree_change(ll now,ll to)
{
if(tree[now].l==tree[now].r)
{
tree[now].mi=X;
tree[now].ma=X;
tree[now].sum=X;
return ;
}
if(tree[now].flag) tree_down(now);
if(to<=tree[now].mid) tree_change(now<<,to);
else tree_change(now<<|,to);
tree[now].sum=tree[now<<].sum+tree[now<<|].sum;
tree[now].ma=max(tree[now<<].ma,tree[now<<|].ma);
tree[now].mi=min(tree[now<<].mi,tree[now<<|].mi);
} void tree_change_(ll now,ll l,ll r)
{
if(tree[now].l==l&&tree[now].r==r)
{
tree[now].flag=!tree[now].flag;
ll mii=tree[now].mi,maa=tree[now].ma;
tree[now].sum=-tree[now].sum;
tree[now].ma=-mii,tree[now].mi=-maa;
return ;
}
if(tree[now].flag) tree_down(now);
if(l>tree[now].mid) tree_change_(now<<|,l,r);
else if(r<=tree[now].mid) tree_change_(now<<,l,r);
else tree_change_(now<<,l,tree[now].mid),tree_change_(now<<|,tree[now].mid+,r);
tree[now].sum=tree[now<<].sum+tree[now<<|].sum;
tree[now].ma=max(tree[now<<].ma,tree[now<<|].ma);
tree[now].mi=min(tree[now<<].mi,tree[now<<|].mi);
} void solve_change(ll x,ll y)
{
while(top[x]!=top[y])
{
if(deep[top[x]]<deep[top[y]]) swap(x,y);
tree_change_(,id[top[x]],id[x]);
x=f[top[x]];
}
if(deep[x]>deep[y]) swap(x,y);
if(x!=y) tree_change_(,id[x]+,id[y]);
} void solve_query(ll x,ll y)
{
while(top[x]!=top[y])
{
if(deep[top[x]]<deep[top[y]]) swap(x,y);
tree_query(,id[top[x]],id[x]);
x=f[top[x]];
}
if(deep[x]>deep[y]) swap(x,y);
if(x!=y) tree_query(,id[x]+,id[y]);
} int main()
{
freopen("nt2011_travel.in","r",stdin);
freopen("nt2011_travel.out","w",stdout);
in(n);ll u,v,w;
for(ll i=;i<n;i++)
{
in(u),in(v),in(w);
edge_add(u,v,w);
ps[i]=u,pe[i]=v;
}
cnt=,pre(,-),dfs(,,);
tree_build(,,n);
in(m);char ch[];
while(m--)
{
scanf("%s",ch);in(u),in(v);
if(ch[]=='N') solve_change(u,v);
else if(ch[]=='C')
{
X=v;
if(deep[ps[u]]>deep[pe[u]]) swap(ps[u],pe[u]);
tree_change(,id[pe[u]]);
}
else if(ch[]=='S') ty=,X=,solve_query(u,v),printf("%lld\n",X);
else if(ch[]=='M')
{
if(ch[]=='A') ty=,X=-INF,solve_query(u,v),printf("%lld\n",X);
else ty=,X=INF,solve_query(u,v),printf("%lld\n",X);
}
}
fclose(stdin),fclose(stdout);
return ;
}

AC日记——[国家集训队2011]旅游(宋方睿) cogs 1867的更多相关文章

  1. AC日记——[国家集训队2010]小Z的袜子 cogs 1775

    [国家集训队2010]小Z的袜子 思路: 传说中的莫队算法(优雅的暴力): 莫队算法是一个离线的区间询问算法: 如果我们知道[l,r], 那么,我们就能O(1)的时间求出(l-1,r),(l+1,r) ...

  2. cogs 1901. [国家集训队2011]数颜色

    Cogs 1901. [国家集训队2011]数颜色 ★★★   输入文件:nt2011_color.in   输出文件:nt2011_color.out   简单对比时间限制:0.6 s   内存限制 ...

  3. BZOJ 2150 cogs 1861 [国家集训队2011]部落战争

    题目描述 lanzerb的部落在A国的上部,他们不满天寒地冻的环境,于是准备向A国的下部征战来获得更大的领土. A国是一个M*N的矩阵,其中某些地方是城镇,某些地方是高山深涧无人居住.lanzerb把 ...

  4. happiness[国家集训队2011(吴确)]

    [试题来源] 2011中国国家集训队命题答辩 [问题描述] 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科 ...

  5. COGS1882 [国家集训队2011]单选错位

    ★   输入文件:nt2011_exp.in   输出文件:nt2011_exp.out   简单对比时间限制:1 s   内存限制:512 MB [试题来源] 2011中国国家集训队命题答辩 [问题 ...

  6. 1893. [国家集训队2011]等差子序列(bitset)

    ★★   输入文件:nt2011_sequence.in   输出文件:nt2011_sequence.out   简单对比时间限制:0.3 s   内存限制:512 MB [试题来源] 2011中国 ...

  7. bzoj2144 【国家集训队2011】跳跳棋

    Description 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子.我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置.我们要通过最少的跳动把他 ...

  8. COGS.1901.[模板][国家集训队2011]数颜色(带修改莫队)

    题目链接 COGS BZOJ2120 洛谷P1903 /* Add和Subd函数中的vis不能直接设为=1或=0 比如 l=1,r=0 -> l=3,r=5 时,[1,5]的vis标记全都是1 ...

  9. COGS1871 [国家集训队2011]排队(魏铭)

    bzoj:http://www.lydsy.com/JudgeOnline/problem.php?id=2141 cogs:http://cogs.pro:8080/cogs/problem/pro ...

随机推荐

  1. error LNK2001: unresolved external symbol @__security_check_cookie

    Q:VS2005编译的静态库, 在vc++6.0中连接出现错误 error LNK2001: unresolved external symbol @__security_check_cookie@l ...

  2. 底部菜单栏之Fragment的详细介绍和使用方法

    详情请看:http://blog.csdn.net/loongggdroid/article/details/9366413

  3. Oracle 学习---- 练习语法 循环( loop end loop; for ;while; if elsif end if )

    /*--set serveroutput on;declare mynum number(3) :=0; tip varchar2(10):='结果是 ';begin mynum:=10+100; d ...

  4. NGUI执行基本事件的原理

    通常我们为对象附加一个脚本组件,脚本组件只要加此鼠标处理事件方法,这个对象就有了点击事件了: void OnClick() { Debug.Log("onclick"); } 可为 ...

  5. Linux & Windows 查看 ip 地址

    Windows 查看本机 IP 打开 cmd,输入 ipconfig,回车,找到IPv4地址 或者通过以下方式查看 点击Win10系统的右下角的宽带连接图标,如下图所示.        点击弹出菜单的 ...

  6. 原始套接字--简易ping程序

    #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> ...

  7. tarjan算法求LCA

    tarjan算法求LCA LCA(Least Common Ancestors)的意思是最近公共祖先,即在一棵树中,找出两节点最近的公共祖先. 这里我们使用tarjan算法离线算法解决这个问题. 离线 ...

  8. Virtual box 虚拟机 不可使用的一种解决方法

    在win7下开着一个ubuntu虚拟机,写了好几小时代码,然后饿了,去吃点东西 回来发现,电脑由于win7 自动更新已经重启 ubuntu下的代码我已经走开时保存过了,所以不怎么担心 但是打开virt ...

  9. Problem 1036 四塔问题

    Accept: 590    Submit: 1506Time Limit: 1000 mSec    Memory Limit : 32768 KB  Problem Description “汉诺 ...

  10. poj1936 假期计划第一水

    All in All Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 29651   Accepted: 12312 Desc ...