AC日记——[国家集训队2011]旅游(宋方睿) cogs 1867
思路:
树链剖分,边权转点权;
线段树维护三个东西,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的更多相关文章
- AC日记——[国家集训队2010]小Z的袜子 cogs 1775
[国家集训队2010]小Z的袜子 思路: 传说中的莫队算法(优雅的暴力): 莫队算法是一个离线的区间询问算法: 如果我们知道[l,r], 那么,我们就能O(1)的时间求出(l-1,r),(l+1,r) ...
- cogs 1901. [国家集训队2011]数颜色
Cogs 1901. [国家集训队2011]数颜色 ★★★ 输入文件:nt2011_color.in 输出文件:nt2011_color.out 简单对比时间限制:0.6 s 内存限制 ...
- BZOJ 2150 cogs 1861 [国家集训队2011]部落战争
题目描述 lanzerb的部落在A国的上部,他们不满天寒地冻的环境,于是准备向A国的下部征战来获得更大的领土. A国是一个M*N的矩阵,其中某些地方是城镇,某些地方是高山深涧无人居住.lanzerb把 ...
- happiness[国家集训队2011(吴确)]
[试题来源] 2011中国国家集训队命题答辩 [问题描述] 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科 ...
- COGS1882 [国家集训队2011]单选错位
★ 输入文件:nt2011_exp.in 输出文件:nt2011_exp.out 简单对比时间限制:1 s 内存限制:512 MB [试题来源] 2011中国国家集训队命题答辩 [问题 ...
- 1893. [国家集训队2011]等差子序列(bitset)
★★ 输入文件:nt2011_sequence.in 输出文件:nt2011_sequence.out 简单对比时间限制:0.3 s 内存限制:512 MB [试题来源] 2011中国 ...
- bzoj2144 【国家集训队2011】跳跳棋
Description 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子.我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置.我们要通过最少的跳动把他 ...
- COGS.1901.[模板][国家集训队2011]数颜色(带修改莫队)
题目链接 COGS BZOJ2120 洛谷P1903 /* Add和Subd函数中的vis不能直接设为=1或=0 比如 l=1,r=0 -> l=3,r=5 时,[1,5]的vis标记全都是1 ...
- COGS1871 [国家集训队2011]排队(魏铭)
bzoj:http://www.lydsy.com/JudgeOnline/problem.php?id=2141 cogs:http://cogs.pro:8080/cogs/problem/pro ...
随机推荐
- USACO Section2.3 Zero Sum 解题报告 【icedream61】
zerosum解题报告----------------------------------------------------------------------------------------- ...
- 【Noise and Probabilistic Target】林轩田机器学习基石
http://beader.me/mlnotebook/section2/noise-and-error.html 上面这个日志总结的已经很好了.这一章的内容,在后面具体的算法中cost functi ...
- ACM二分搜索算法
二分搜索算法就是把要搜索的数据在搜索文本中根据情况进行折半,比如要在2 6 4 9 3 8 7 3 5中找到找到4的位置,那么可以考虑先把数据进行排序,然后把拍好后的数据的中间的那个数据和要查找的数据 ...
- Percona-Tookit工具包之pt-table-usage
Preface There always be some table join operations in our SQL statement.Although we can know ...
- sql 表数据转移另一张表
if not exists(select * from syscolumns where id=object_id('REMOTEDETECTION_2018')) begin SELECT * I ...
- Pacemaker、corosync
pacemaker详细介绍: http://blog.51cto.com/freeloda/1274533 corosync详细介绍: http://blog.51cto.com/freeloda/1 ...
- 团队冲刺Alpha(六)
目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:凯琳 组员6:翟丹丹 组员7:何家伟 组员8:政演 组员9:黄鸿杰 组员10:刘一好 组员11:何宇恒 展示 ...
- 什么是SQL注入?(理解)
SQL注入攻击是黑客对数据库进行攻击的常用手段之一.一部分程序员在编写代码的时候,没有对用户输入数据的合法性进行判断,注入者可以在表单中输入一段数据库查询代码并提交,程序将提交的信息拼凑生成一个完整s ...
- 当发送ICMP包的时候不一定能收得到(arp已经应答了)【复现不了了】
arp已经应答了,然后再返回ICMP应答的时候竟然不被回复. 其实这里想想也很容易想清楚: 虽然arp给了回复,但是真正到ICMP报文到的时候,我理解报文到的时候,我理解还是要进行与本地网络兑换的,本 ...
- JVM垃圾回收机制GC
1. 垃圾回收的意义 在C++中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前不能分配给其它对象:而在Java中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾.JVM的 ...