SPOJ GSS7 && Vijos1620 【LCT】

3 篇文章 0 订阅
1 篇文章 0 订阅

题意:给定一棵有点权的树。

支持操作:

1.修改(u,v)这条路径上的点权

2.询问(u,v)这条路径上的连续的点权的最大值。


这道题应该可以用树链剖分做。不过鉴于我正在学LCT那就用LCT好了~

应该算是比较裸的LCT了吧。维护lmax、rmax、smax、sum即可回答。修改的时候打个标记就行。


Vijos上0.6s,SPOJ上17s。。这什么差距。。


贴代码~

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

#define inf 0x7fffffff
#define max(a,b) (((a)>(b))?(a):(b)) 
struct LinkCutTree{
    #define S 200010
    int pp[S],ch[S][2],fa[S],val[S],sz[S],lmax[S],rmax[S],smax[S],sum[S],same[S];
    
    #define ls ch[x][0]
    #define rs ch[x][1]
    inline void pushup(int x){
        sz[x]=sz[ls]+sz[rs]+1;
        sum[x]=sum[ls]+sum[rs]+val[x];
        lmax[x]=max(lmax[ls],sum[ls]+val[x]+lmax[rs]);
        rmax[x]=max(rmax[rs],sum[rs]+val[x]+rmax[ls]);
        smax[x]=max(max(smax[ls],smax[rs]),rmax[ls]+val[x]+lmax[rs]);
    }
    
    inline void pushdown(int x){
        if(same[x]!=inf){
            if(ls){
                same[ls]=val[ls]=same[x];
                sum[ls]=same[x]*sz[ls];
                lmax[ls]=rmax[ls]=smax[ls]=max(sum[ls],0);
            }
            if(rs){
                same[rs]=val[rs]=same[x];
                sum[rs]=same[x]*sz[rs];
                lmax[rs]=rmax[rs]=smax[rs]=max(sum[rs],0);
            }
            same[x]=inf;
        }
    }
    inline void rotate(int x,int f){
        int y=fa[x],z=fa[y];
        pushdown(y);
        pushdown(x);
        ch[y][!f]=ch[x][f];
        fa[ch[x][f]]=y;
        ch[z][ch[z][1]==y]=x;
        fa[x]=z;
        ch[x][f]=y;
        fa[y]=x;
        pushup(y);
    }
    
    inline void splay(int x){
        int p;
        for(p=x;fa[p];p=fa[p]);
        if(p!=x){
            pp[x]=pp[p];
            pp[p]=0;
            while(fa[x])    rotate(x,ch[fa[x]][0]==x);
            pushup(x);
        }else   pushdown(x);
    }
    
    inline void access(int x){
        for(int p=0;x;x=pp[x]){
            splay(x);   
            pp[rs]=x;   
            fa[rs]=0;
            rs=p;   
            pp[rs]=0;    
            fa[rs]=x;
            p=x;
            pushup(x);
        }
    }
       
    inline void update(int x,int y,int v){
        access(y);
        for(y=0;x;x=pp[x]){
            splay(x);
            if(!pp[x]){
                val[x]=v;
                if(y){
                    val[y]=same[y]=v;
                    sum[y]=v*sz[y];
                    lmax[y]=rmax[y]=smax[y]=max(0,v);
                }
                if(rs){
                    y=rs;
                    val[y]=same[y]=v;
                    sum[y]=v*sz[y];
                    lmax[y]=rmax[y]=smax[y]=max(0,v);
                }
            }
            pp[rs]=x;
            fa[rs]=0;
            rs=y;
            fa[rs]=x;
            pp[rs]=0;
            y=x;
            pushup(x);
        }
    }
    
    inline int query(int x,int y){
        int ans;
        access(y);
        for(y=0;x;x=pp[x]){
            splay(x);
            if(!pp[x])  return max(max(smax[y],smax[rs]),val[x]+lmax[y]+lmax[rs]);
            pp[rs]=x;
            fa[rs]=0;
            rs=y;
            fa[rs]=x;
            pp[rs]=0;
            y=x;
            pushup(x);
        }
        return 0;
    }
}LCT;

#define maxn 200010
#define maxm 400020
struct edge{
    int t,next;
}E[maxm];
int V[maxn],tot=0;

inline void addedge(int x,int y){
    E[tot].t=y;E[tot].next=V[x];V[x]=tot++;
}

int vis[maxn],q[maxn];
inline void bfs(int x){
    int head=0,tail=1;
    memset(vis,0,sizeof(vis));
    vis[x]=true;
    q[head]=x;
    while(head!=tail){
        int u=q[head++];
        for(int p=V[u];p!=-1;p=E[p].next){
            int v=E[p].t;
            if(!vis[v]){
                LCT.pp[v]=u;
                LCT.same[v]=inf;
                vis[v]=true;
                q[tail++]=v;
            }
        }
    }
}

inline void init(){
    memset(V,0xff,sizeof(V));
    tot=0;
}

inline void read(int &x){
    char ch;    int f=1;
    for(ch=getchar();(ch!='-')&&(ch<'0'||ch>'9');ch=getchar());
    if(ch=='-') f=-1,x=0;   else    x=ch-'0';
    for(ch=getchar();ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
    x*=f;
}

int main(){
    int n,u,v,x,y,q,op;
    read(n); 
    init();
    for(int i=1;i<=n;i++){
        read(LCT.val[i]);
        LCT.same[i]=inf;
    }
    for(int i=1;i<n;i++){
        read(u);
        read(v);
        addedge(u,v);
        addedge(v,u);
    }
    bfs(1);
    read(q);
    int flag=0;
    while(q--){
        read(op);
        if(op==1){
            read(x);
            read(y);
            if(flag)printf(" ");    else flag=1;
            printf("%d",LCT.query(x,y));
        }else{
            read(x);
            read(y);
            read(v);
            LCT.update(x,y,v);
        }
    }
    printf("\n");
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
洛谷的SPOJ需要注册一个SPOJ账号并进行绑定才能进行交题。您可以按照以下步骤进行注册: 1. 打开洛谷网站(https://www.luogu.com.cn/)并登录您的洛谷账号。 2. 在网站顶部导航栏中找到“题库”选项,将鼠标悬停在上面,然后选择“SPOJ”。 3. 在SPOJ页面上,您会看到一个提示,要求您注册SPOJ账号并进行绑定。点击提示中的链接,将会跳转到SPOJ注册页面。 4. 在SPOJ注册页面上,按照要求填写您的用户名、密码和邮箱等信息,并完成注册。 5. 注册完成后,返回洛谷网站,再次进入SPOJ页面。您会看到一个输入框,要求您输入刚刚注册的SPOJ用户名。输入用户名后,点击“绑定”按钮即可完成绑定。 现在您已经成功注册并绑定了SPOJ账号,可以开始在洛谷的SPOJ题库上刷题了。祝您顺利完成编程练习!\[1\]\[2\] #### 引用[.reference_title] - *1* *3* [(洛谷入门系列,适合洛谷新用户)洛谷功能全解](https://blog.csdn.net/rrc12345/article/details/122500057)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [luogu p7492 序列](https://blog.csdn.net/zhu_yin233/article/details/122051384)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值