首页 > 其他分享 >CSP模拟58联测20 T3 注视一切的终结

CSP模拟58联测20 T3 注视一切的终结

时间:2023-10-19 19:46:03浏览次数:33  
标签:20 58 int T3 tot edge maxn lca

CSP模拟58联测20 T3 注视一切的终结

题面及数据范围

Ps:链接为衡水中学OJ。

去除重边以后是树,而我们需要使一个点到另外一个点的简单路径上相邻边的颜色尽可能不相同。

发现如果一条边有 \(3\) 种或以上的颜色,那么该边肯定可以与相邻边不同,所以把 \(\geq3\) 的情况均看为 \(3\) 的情况。

然后把边权下压至儿子的点权。

可以 \(log_2n\) 的倍增求出 \(lca\) 同时也可以通过倍增求最大贡献。

设 \(f[u][i][a][b]\) 表示从 \(u\) 向上跳 \(2^i\) 步,开始颜色为 \(a\),结束颜色为 \(b\) 的最大贡献,其中 \(a \leq 3,b \leq 3\)。(实际上已经跳到了 \(2^i+1\) 这个点,但因为点权是连向父亲的边权,所以我们不需要 \(2^i+1\) 这个点的点权)

初始时 \(f[u][0][a][b]=col[a]\neq col[b]\)。

转移时枚举 \(x,y=fa[x][i-1],z=fa[x][i]\) ,设颜色为 \(a,b,c\) 则 \(f[x][i][a][c]=\max(f[x][i-1][a][b]+f[y][i-1][b][c])\)。

其中 \(z\) 是用来枚举终点的颜色。

对于查询,先求出 \(lca\)。

如果 \(lca=x\) 或 \(lca=y\) 那么直接求出另一点的 \(lca\) 的最大值;否则在枚举最后两条边的颜色。

#include<bits/stdc++.h>
using namespace std;

const int maxn=5e5+5;

struct node
{
    int to,nxt,w;
}edge[maxn*4];

int n,m,tot;
int head[maxn],dp[maxn][22][4][4],f[maxn][21],deep[maxn],col[maxn][5],cx[5],cy[5],cnt[maxn];

bool vis[maxn];

void add(int x,int y,int z)
{
    tot++;
    edge[tot].to=y;
    edge[tot].nxt=head[x];
    edge[tot].w=z;
    head[x]=tot;
}

void dfs1(int u,int fa)
{
    vis[u]=true;
    for(int i=head[u];i;i=edge[i].nxt)
    {
        int v=edge[i].to;
        if(v==fa)
        {
            if(cnt[u]==3) continue;
            bool flg=1;
            for(int j=0;j<cnt[u];j++) if(col[u][j]==edge[i].w){flg=0;break;}
            if(flg) col[u][cnt[u]++]=edge[i].w;
        }
        else if(!vis[v]) dfs1(v,u);
    }
}
void dfs2(int u,int fa)
{
    vis[u]=true;
    deep[u]=deep[fa]+1;
    f[u][0]=fa;
    if(u!=1)
    {
        for(int a=0;a<cnt[u];a++)//初始化
            for(int b=0;b<cnt[fa];b++)
                dp[u][0][a][b]=(col[u][a]!=col[fa][b]);
    }
    for(int i=1;(1<<i)<=deep[u];i++)//dp 转移
    {
        f[u][i]=f[f[u][i-1]][i-1];
        int y=f[u][i-1],z=f[u][i];
        for(int a=0;a<cnt[u];a++)//a,b,c 均枚举颜色
            for(int b=0;b<cnt[y];b++)
                for(int c=0;c<cnt[z];c++) dp[u][i][a][c]=max(dp[u][i][a][c],dp[u][i-1][a][b]+dp[y][i-1][b][c]);
    }
    for(int i=head[u];i;i=edge[i].nxt)
    {
        int v=edge[i].to;
        if(vis[v]) continue;
        dfs2(v,u);
    }
}

int Lca(int x,int y)
{
    if(deep[x]<deep[y]) swap(x,y);
    for(int i=20;i>=0;i--) if(deep[f[x][i]]>=deep[y]) x=f[x][i];
    if(x==y) return x;
    for(int i=20;i>=0;i--) if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
    return f[x][0];
}
int jump(int x,int dis,int c[])//点 x 向上跳 dis 步的最大答案
{
    int now=x;
    for(int i=0;i<=20;i++)
    {
        if(((dis>>i)&1)==0) continue;
        int cc[5];
        memset(cc,0,sizeof(cc));
        for(int a=0;a<cnt[now];a++)
            for(int b=0;b<cnt[f[now][i]];b++) cc[b]=max(cc[b],c[a]+dp[now][i][a][b]);
        memcpy(c,cc,sizeof(cc));
        now=f[now][i];
    }
    return now;
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
        add(y,x,z);
    }

    dfs1(1,0);
    memset(vis,0,sizeof(vis));
    dfs2(1,0);

    int q;
    scanf("%d",&q);
    for(int qq=1;qq<=q;qq++)
    {
        int x,y;
        memset(cx,0,sizeof(cx)),memset(cy,0,sizeof(cy));
        scanf("%d%d",&x,&y);
        int lca=Lca(x,y),fx,fy,ans=0;
        if(x!=lca) fx=jump(x,deep[x]-deep[lca]-1,cx);
        if(y!=lca) fy=jump(y,deep[y]-deep[lca]-1,cy);
        if(x==lca) for(int i=0;i<cnt[fy];i++) ans=max(ans,cy[i]);
        else if(y==lca) for(int i=0;i<cnt[fx];i++) ans=max(ans,cx[i]);
        else
            for(int a=0;a<cnt[fx];a++)
                for(int b=0;b<cnt[fy];b++) ans=max(ans,cx[a]+cy[b]+(col[fx][a]!=col[fy][b]));//最后枚举颜色
        printf("%d\n",ans);
    }
}

标签:20,58,int,T3,tot,edge,maxn,lca
From: https://www.cnblogs.com/binbinbjl/p/17775454.html

相关文章

  • P1525 [NOIP2010 提高组] 关押罪犯
    P1525[NOIP2010提高组]关押罪犯法一:二分图把犯人分配到两个监狱,使得监狱内的怒气值最大最小分配到两个集合中,考虑二分染色分析因为答案具有单调性所以可以二分:判断x是否符合,只需要重建大于x的边,如果不能把它们分到两个集合中(二分染色失败),就往上调(考虑无限大,那么就不矛盾)......
  • 山东省实验中学 2023 秋提高级友好学校赛前联测 3 T2
    琼玉牌(qiongyu)题目描述青雀正在玩「帝垣琼玉」牌。「帝垣琼玉」牌有\(3\)种不同花色的琼玉牌,青雀的桌子上有\(4\)个放牌的位置,最开始青雀的牌桌上没有琼玉牌。青雀会进行\(n\)回合的抽牌。每个回合开始时,青雀会从牌堆里立即随机抽取\(2\)次牌(牌堆里每种牌都有无......
  • 软考系列(系统架构师)- 2018年系统架构师软考案例分析考点
    试题一软件架构(非功能性需求、C/S架构)【问题1】(8分)在系统架构设计中,决定系统架构设计的非功能性需求主要有四类:操作性需求、性能需求、安全性需求和文化需求。请简要说明四类需求的含义。(1)操作性需求:指系统完成任务所需的操作环境要求及如何满足系统将来可能的需求变更的......
  • 山东省实验中学 2023 秋提高级友好学校赛前联测 3 T3
    零一串(string)题目描述给定一个长度为\(n\)的01串,你需要将它划分成若干段,每一段的长度都不超过\(m\),且满足以下两种条件之一:这个段中全部为\(0\)或全部为\(1\).这个段中\(0,1\)数量之差不超过\(k\).你需要求出该01串合法的划分最少要多少段。输入格式第......
  • 15-DS18B20温度传感器的基本应用
    DS18B20温度传感器的基本应用DS18B20是Dallas半导体公司的一款数字温度传感器芯片DS18B20是一款支持1-wire总线接口的温度传感器DS18B20的温度范围-55\(^{\circ}\)C-125\(^{\circ}\)C,精度为\(\pm0.5^{\circ}\)CDS18B20可将分辨率设置为9到12位DS18B20的工作电压范围3-5.5vDS......
  • CSP 2023 游记
    Day-2上午模拟赛没好好打,本来T2想到拉插了没写,于是一上午荒废了。中午睡觉时候把《平凡的世界》第一部看完了。中午起床以后就开始想吐,可能是午饭宫保鸡丁里花生米搞的鬼。当时5k就发了烧了,他过了一会就去休息了,只好把HE-CSP2023贺图的事接过来,于是一下午荒废了。晚上......
  • 山东省实验中学 2023 秋提高级友好学校赛前联测 3 T1
    生成树(tree)题目描述给定一棵\(n\)个节点的树。定义这棵树的生成完全图为一个\(n\)个节点的完全图,图中两点\(u,v\)的边权为这两点在树上简单路径上的边权和。请你求出这张完全图的最小生成树和最大生成树,分别输出两种生成树的边权之和。输入格式第一行输入一个正整......
  • 2023年10月整理书单列表
       ......
  • SpringBoot3.0 + RocketMq 构建企业级数据中台[内附资料]
    点击下载:SpringBoot3.0+RocketMq构建企业级数据中台[内附资料]  提取码:3cnfSpringBoot3.0是SpringBoot框架的最新版本,它提供了愈加简单、快速和高效的方式来构建企业级应用程序。RocketMq是一款高性能的音讯中间件,能够完成散布式音讯传送和处置。将SpringBoot3.0和Rocket......
  • 神策数据《2023 中国客户旅程编排(CJO)应用指南》开启预约领取
    基于对数字化转型时代触点红利与企业发展的深入洞察,神策数据围绕客户旅程编排(CustomerJourneyOrchestration,简称CJO)进行全面研究,旨在为更多企业数字化转型过程中重塑客户体验、挖掘增量机会、节省长期投入等提供科学有效的方法论指导。今日,神策数据《2023中国客户旅程编排(CJO)应......