SPOJ GSS7 Can you answer these queries VII ——树链剖分 线段树
【题目分析】
问题放到了树上,直接链剖+线段树搞一搞。
调了300行+。
(还是码力不够)
【代码】
- #include <cstdio>
- #include <cstring>
- #include <cmath>
- #include <cstdlib>
- #include <map>
- #include <set>
- #include <queue>
- #include <string>
- #include <iostream>
- #include <algorithm>
- using namespace std;
- #define maxn 1000005
- #define eps 1e-8
- #define db double
- #define ll long long
- #define inf 0x3f3f3f3f
- #define F(i,j,k) for (int i=j;i<=k;++i)
- #define D(i,j,k) for (int i=j;i>=k;--i)
- void Finout()
- {
- #ifndef ONLINE_JUDGE
- freopen("in.txt","r",stdin);
- freopen("wa.txt","w",stdout);
- #endif
- }
- int Getint()
- {
- int x=0,f=1; char ch=getchar();
- while (ch<'0'||ch>'9') {if (ch=='-') f=-1; ch=getchar();}
- while (ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}
- return x*f;
- }
- struct Node{
- int lx,rx,mx,sum,lazy;
- Node operator + (Node x)
- {
- Node ret;
- ret.lx=max(lx,sum+x.lx);
- ret.rx=max(x.sum+rx,x.rx);
- ret.sum=sum+x.sum;
- ret.mx=max(max(mx,x.mx),max(rx+x.lx,max(ret.lx,ret.rx)));
- ret.lazy=-inf;
- return ret;
- }
- void print()
- {
- printf("lx %d rx %d sum %d mx %d lazy %d\n",lx,rx,sum,mx,lazy);
- }
- void init(){lx=rx=mx=sum=0;lazy=-inf;}
- }t[maxn];
- int n,a[maxn],b[maxn],q,L,R,tot,x,y,c;
- int h[maxn],to[maxn],ne[maxn],en=0;
- int fa[maxn],top[maxn],dep[maxn],siz[maxn],pos[maxn],son[maxn];
- void add(int a,int b)
- {
- to[en]=b; ne[en]=h[a]; h[a]=en++;
- to[en]=a; ne[en]=h[b]; h[b]=en++;
- }
- void build(int o,int l,int r)
- {
- if (l==r)
- {
- t[o].lx=t[o].rx=t[o].mx=t[o].sum=a[l];
- t[o].lazy=-inf;
- return ;
- }
- int mid=l+r>>1;
- build(o<<1,l,mid);
- build(o<<1|1,mid+1,r);
- t[o]=t[o<<1]+t[o<<1|1];
- t[o].lazy=-inf;
- }
- void dfs1(int o)
- {
- siz[o]=1;
- for (int i=h[o];i>=0;i=ne[i])
- {
- if (to[i]!=fa[o])
- {
- fa[to[i]]=o;
- dep[to[i]]=dep[o]+1;
- dfs1(to[i]);
- siz[o]+=siz[to[i]];
- if (siz[to[i]]>siz[son[o]]) son[o]=to[i];
- }
- }
- }
- void dfs2(int o,int tp)
- {
- top[o]=tp;
- pos[o]=++tot;
- a[tot]=b[o];
- if (!son[o]) return ;
- dfs2(son[o],tp);
- for (int i=h[o];i>=0;i=ne[i])
- if ((to[i]!=fa[o])&&(to[i]!=son[o]))
- dfs2(to[i],to[i]);
- return ;
- }
- Node q1[maxn],q2[maxn];
- void cov(int o,int c,int l,int r)
- {
- // printf("Node %d %d %d %d\n",o,c,l,r);
- t[o].lx=c<0?c:(r-l+1)*c; //printf("%d %d\n",c,(l-r+1)*c);
- t[o].rx=c<0?c:(r-l+1)*c;
- t[o].sum=(r-l+1)*c;
- t[o].mx=c<0?c:(r-l+1)*c;
- // printf("lx:%d rx:%d sum:%d mx:%d\n",t[o].lx,t[o].rx,t[o].sum,t[o].mx);
- }
- void pushdown(int o,int l,int r)
- {
- int mid=l+r>>1;
- if (t[o].lazy!=-inf)
- {
- // printf("pushdown %d\n",o);
- // printf("in %d\n",t[o].lazy);
- t[o<<1].lazy=t[o<<1|1].lazy=t[o].lazy;
- cov(o<<1,t[o].lazy,l,mid);
- cov(o<<1|1,t[o].lazy,mid+1,r);
- }
- t[o].lazy=-inf;
- }
- Node Query(int o,int l,int r)
- {
- // printf("q down\n");
- pushdown(o,l,r);
- // printf("Query %d %d\n",l,r);
- if (L<=l&&r<=R) return t[o];
- int mid=l+r>>1;
- if (L>mid) return Query(o<<1|1,mid+1,r);
- else if (R<=mid) return Query(o<<1,l,mid);
- else return Query(o<<1,l,mid)+Query(o<<1|1,mid+1,r);
- }
- void query()
- {
- x=Getint(); y=Getint();
- // printf("Query %d to %d\n",x,y);
- int p1=0,p2=0;
- while (top[x]!=top[y])
- {
- if (dep[top[x]]>dep[top[y]])
- {
- L=pos[top[x]]; R=pos[x];
- q1[++p1]=Query(1,1,n);
- // printf("Query %d %d\n",L,R);
- // printf("at q1\n"); q1[p1].print();
- // printf("x: %d to %d\n",x,fa[top[x]]);
- x=fa[top[x]];
- }
- else
- {
- L=pos[top[y]]; R=pos[y];
- // printf("%d %d\n",L,R);
- q2[++p2]=Query(1,1,n);
- // printf("Query %d %d\n",L,R);
- // printf("at q2\n"); q2[p2].print();
- // printf("y: %d to %d\n",y,fa[top[y]]);
- y=fa[top[y]];
- }
- }
- if (dep[x]>=dep[y])
- {
- L=pos[y]; R=pos[x];
- // printf("%d %d\n",L,R);
- q1[++p1]=Query(1,1,n);
- // printf("Query %d %d\n",L,R);
- // printf("at q1\n"); q1[p1].print();
- }
- else
- {
- L=pos[x]; R=pos[y];
- // printf("%d %d\n",L,R);
- q2[++p2]=Query(1,1,n);
- // printf("Query %d %d\n",L,R);
- // printf("at q2\n"); q2[p2].print();
- }
- /* Node ret1,ret2,ret; ret1.init();ret2.init();ret.init();
- printf("q1begin\n");
- D(i,p1,1)
- {
- ret1.print();
- ret1=ret1+q1[i];
- q1[i].print();
- ret1.print();
- }
- printf("q1 over\n");
- ret1.print();
- printf("q2 begin\n");
- D(i,p2,1)
- {
- ret2.print();
- ret2=ret2+q2[i];
- q2[i].print();
- ret2.print();
- }
- printf("q2 over\n");
- // ret1.init(); ret2.init();
- ret1.print(); ret2.print();
- swap(ret2.lx,ret2.rx);
- ret=ret1+ret2;
- */
- Node ret,ret1,ret2; ret.init(); ret1.init(); ret2.init();
- if (!p1)
- {
- // printf("only p2\n");
- ret=q2[1];
- F(i,2,p2) ret=q2[i]+ret;
- }
- else if (!p2)
- {
- // printf("only p1\n");
- ret=q1[1];
- F(i,2,p1) ret=q1[i]+ret;
- }
- else
- {
- // printf("both p1 and p2\n");
- ret1=q1[1];
- F(i,2,p1) ret1=q1[i]+ret1;
- ret2=q2[1];
- F(i,2,p2) ret2=q2[i]+ret2;
- swap(ret2.lx,ret2.rx);
- ret=ret2+ret1;
- }
- printf("%d\n",max(ret.mx,0));
- }
- void mod(int o,int l,int r)
- {
- // printf("mod %d %d %d\n",o,l,r);
- pushdown(o,l,r);
- int mid=l+r>>1;
- if (L<=l&&r<=R)
- {
- // printf("tag on %d by %d %d to %d\n",o,c,l,r);
- t[o].lazy=c;
- cov(o,c,l,r);
- return ;
- }
- if (L<=mid) mod(o<<1,l,mid);
- if (R>mid) mod(o<<1|1,mid+1,r);
- t[o]=t[o<<1]+t[o<<1|1];
- }
- void Modify()
- {
- x=Getint(); y=Getint(); c=Getint();
- while (top[x]!=top[y])
- {
- if (dep[top[x]]<dep[top[y]]) swap(x,y);
- L=pos[top[x]]; R=pos[x];
- // printf("modify %d %d %d\n",L,R,c);
- mod(1,1,n);
- x=fa[top[x]];
- }
- if (dep[x]<dep[y]) swap(x,y);
- L=pos[y]; R=pos[x];
- // printf("modify %d %d %d\n",L,R,c);
- mod(1,1,n);
- }
- int main()
- {
- memset(h,-1,sizeof h);
- Finout(); n=Getint();
- F(i,1,n) b[i]=Getint();
- F(i,1,n-1) add(Getint(),Getint());
- dfs1(1); dep[0]=-1;
- dfs2(1,1);
- // F(i,1,n) printf("Node %d : fa %d pos %d dep %d\n",i,fa[i],pos[i],dep[i]);
- build(1,1,n);
- q=Getint();
- F(i,1,q)
- {
- int opt=Getint();
- switch(opt)
- {
- case 1: query(); break;
- case 2: Modify(); break;
- }
- }
- }
SPOJ GSS7 Can you answer these queries VII ——树链剖分 线段树的更多相关文章
- GSS7 spoj 6779. Can you answer these queries VII 树链剖分+线段树
GSS7Can you answer these queries VII 给出一棵树,树的节点有权值,有两种操作: 1.询问节点x,y的路径上最大子段和,可以为空 2.把节点x,y的路径上所有节点的权 ...
- SPOJ QTREE Query on a tree 树链剖分+线段树
题目链接:http://www.spoj.com/problems/QTREE/en/ QTREE - Query on a tree #tree You are given a tree (an a ...
- SPOJ QTREE Query on a tree ——树链剖分 线段树
[题目分析] 垃圾vjudge又挂了. 树链剖分裸题. 垃圾spoj,交了好几次,基本没改动却过了. [代码](自带常数,是别人的2倍左右) #include <cstdio> #incl ...
- SPOJ GSS7 - Can you answer these queries VII
板的不能再板,链剖+线段树或者是LCT随便维护. 感觉唯一要注意的是跳链的时候要对$x$向上跳和$y$向上跳的情况分开讨论,而不能直接$swap$,因为只有两段接触的端点才能相互合并,而且每一次向上跳 ...
- QTREE3 spoj 2798. Query on a tree again! 树链剖分+线段树
Query on a tree again! 给出一棵树,树节点的颜色初始时为白色,有两种操作: 0.把节点x的颜色置反(黑变白,白变黑). 1.询问节点1到节点x的路径上第一个黑色节点的编号. 分析 ...
- SPOJ 375 (树链剖分+线段树)
题意:一棵包含N 个结点的树,每条边都有一个权值,要求模拟两种操作:(1)改变某条边的权值,(2)询问U,V 之间的路径中权值最大的边. 思路:最近比赛总是看到有树链剖分的题目,就看了论文,做了这题, ...
- spoj QTREE - Query on a tree(树链剖分+线段树单点更新,区间查询)
传送门:Problem QTREE https://www.cnblogs.com/violet-acmer/p/9711441.html 题解: 树链剖分的模板题,看代码比看文字解析理解来的快~~~ ...
- Spoj Query on a tree SPOJ - QTREE(树链剖分+线段树)
You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...
- SP6779 GSS7 - Can you answer these queries VII
纯数据结构题,没有思维难度.直接用线段树求最大子段和的方法完成树上路径的合并.注意链上合并顺序要符合序列的前后顺序. #include <cstdio> #include <cstr ...
随机推荐
- (转)RAM、ROM、SRAM、DRAM、SSRAM、SDRAM、FLASH、EEPROM的区别
RAM(Random Access Memory) 随机存储器.存储单元的内容可按需随意取出或存入,且存取的速度与存储单元的位置无关的存储器.这种存储器在断电时将丢失其存储内容,故主要用于存储短时间使 ...
- Azure 项目构建 - 用 Azure 认知服务在微信公众号上搭建智能会务系统
通过完整流程详细介绍了如何在Azure平台上快速搭建基于微信公众号的智慧云会务管理系统. 此系列的全部课程 https://school.azure.cn/curriculums/11 立即访问htt ...
- ASP.NET MVC执行流程图
- java中的堆与栈
Java 中的堆和栈 Java把内存划分成两种:一种是栈内存,一种是堆内存. 在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配 . 当在一段代码块定义一个变量时,Java就在栈中 ...
- UVA 1347 Tour 双调TSP
TSP是NP难,但是把问题简化,到最右点之前的巡游路线只能严格向右,到最右边的点以后,返回的时候严格向左,这个问题就可以在多项式时间内求出来了. 定义状态d[i][j]表示一个人在i号点,令一个人在j ...
- 国家气象局提供的天气预报接口(完整Json接口)
国家气象局提供的天气预报接口主要有三个,分别是:http://www.weather.com.cn/data/sk/101010100.htmlhttp://www.weather.com.cn/da ...
- STL:string类中size()与length()的区别
结论是:两者没有任何区别 解释: C++Reference中对于两者的解释: 两者的具体解释都一模一样: 理解: length是因为C语言的习惯而保留下来的,string类最初只有length,引进S ...
- 基于KMeans的指数择时策略
[导语]:聚类分析是指将物理或者抽象对象的结合分组为由类似对象组成的多个类的分析过程.简单来讲,聚类就是通过一些特征去自动识别一个大群体中的多个子群体,这些子群体中的对象彼此之间相似度高,而子群体之间 ...
- Caused by: java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/dispatcher-servlet.xml]
这是因为我把 [/WEB-INF/dispatcher-servlet.xml]的位置换成了[config/springmvc/dispatcher-servlet.xml] 因此idea在原来的位置 ...
- flume启动报错
执行flume-ng agent -c conf -f conf/load_balancer_server.conf -n a1 -Dflume.root.logger=DEBUG,console , ...