Codeforces Round 816 (Div. 2)(D拆位图论构造 E斜率优化)

C:直接单独算每个位置的贡献,如果当前位置和前面位置重复了,那么前面就没选的位置了

修改的时候只要重新算i和i+1位置即可

复制代码
#include<bits/stdc++.h>
using namespace std;
const int N=3e5+10,M=2*N,mod=1e9+7;
#define int long long
#define uLL unsigned long long
const long long inf=1e18;
typedef pair<int,int> PII;
typedef long long LL;
using node=tuple<int,int,int>;
int n,m,k;
int a[N];

int calc(int i){
    int res=0;
    int k=n-i+1;
    if(a[i]==a[i-1]) return k;
    return (n-i+1)*(i);
}
void solve()
{
    cin>>n>>m;
    int s=0;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++){
            s+=calc(i);

    }
    a[n+1]=0;
    
    while(m--){
        int x,y;cin>>x>>y;
        s-=calc(x);
        s-=calc(x+1);
        a[x]=y;
        s+=calc(x);
        s+=calc(x+1);
        cout<<s<<"\n";
        //cout<<calc((int)(st.size()))<<"\n";
    }
} 

signed main(){
	cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
	int t=1;
//	cin>>t;
	
	while(t--) solve();
	return 0;
}

D:

拆位,考虑字典序最小,让开头的数能等于0就等于0

要先把一定是0的数和u==v这种确定的数先填了,后面根据字典序填即可

复制代码
#include<bits/stdc++.h>
using namespace std;
const int N=3e5+10,M=2*N,mod=1e9+7;
#define int long long
#define uLL unsigned long long
const long long inf=1e18;
typedef pair<int,int> PII;
typedef long long LL;
using node=tuple<int,int,int>;
int n,m,k;
int a[N];
vector<PII> g[N];
int now[N];

void solve()
{
    cin>>n>>m;
    vector<array<int,3>> a(m);
    for(auto&i:a){
        cin>>i[0]>>i[1]>>i[2];
        g[i[0]].emplace_back(i[1],i[2]);
        g[i[1]].emplace_back(i[0],i[2]);
    }
    vector<int> res(n+10);
    for(int i=30;i>=0;i--)
    {
        memset(now,-1,sizeof(now));
        for(int j=1;j<=n;j++){
            for(auto [v,z]:g[j]){
               
                if(v==j){
                    now[j]=(z>>i&1);continue;
                } 
                if(z>>i&1) continue;
                now[j]=now[v]=0;
            }
        }
        for(int j=1;j<=n;j++)
        {
            if(g[j].size()==0)
            {
                now[j]=0;
            }
            if(now[j]!=-1) continue;
            for(auto [v,z]:g[j])
            {
                if(now[v]==0)//另一个固定了,j只能是1
                {
                    now[j]=1;
                    break;
                }
            }
            if(now[j]==-1)
            {
                for(auto [v,z]:g[j])
                {
                    now[v]=1;
                }
                now[j]=0;
            }
        }    
        for(int j=1;j<=n;j++)
        res[j]+=(now[j])*(1<<i);
    }
    for(int i=1;i<=n;i++) cout<<res[i]<<" ";
} 

signed main(){
	cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
	int t=1;
	//cin>>t;
	
	while(t--) solve();
	return 0;
}

E:

直接斜率优化

考虑每层k进行斜率优化,毕竟转移只会从i-1转移到i层

f[i]=min(f[j]+(i-j)^2)

根据斜率优化式子

f[i]=f[j]+i*i-2*i*j+j*j

f[j]+j*j=2*i*j+f[i]-i*i

y=f[j]+j*j

k=2*i

b=f[i]-i*i

y=kx-b

当i确定的时候让b最小,f[i]一定最小

直接维护凸包即可

复制代码
#include<bits/stdc++.h>
using namespace std;
const int N=3e5+10,M=2*N,mod=1e9+7;
#define int long long
#define uLL unsigned long long
const long long inf=1e18;
typedef pair<int,int> PII;
typedef long long LL;
using node=tuple<int,int,int>;
int n,m,k;
int a[N];
vector<PII> g[N];
int now[N];

void solve()
{
    cin>>n>>m;
    vector<array<int,3>> a(m);
    for(auto&i:a){
        cin>>i[0]>>i[1]>>i[2];
        g[i[0]].emplace_back(i[1],i[2]);
        g[i[1]].emplace_back(i[0],i[2]);
    }
    vector<int> res(n+10);
    for(int i=30;i>=0;i--)
    {
        memset(now,-1,sizeof(now));
        for(int j=1;j<=n;j++){
            for(auto [v,z]:g[j]){
               
                if(v==j){
                    now[j]=(z>>i&1);continue;
                } 
                if(z>>i&1) continue;
                now[j]=now[v]=0;
            }
        }
        for(int j=1;j<=n;j++)
        {
            if(g[j].size()==0)
            {
                now[j]=0;
            }
            if(now[j]!=-1) continue;
            for(auto [v,z]:g[j])
            {
                if(now[v]==0)//另一个固定了,j只能是1
                {
                    now[j]=1;
                    break;
                }
            }
            if(now[j]==-1)
            {
                for(auto [v,z]:g[j])
                {
                    now[v]=1;
                }
                now[j]=0;
            }
        }    
        for(int j=1;j<=n;j++)
        res[j]+=(now[j])*(1<<i);
    }
    for(int i=1;i<=n;i++) cout<<res[i]<<" ";
} 

signed main(){
	cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
	int t=1;
	//cin>>t;
	
	while(t--) solve();
	return 0;
}
相关推荐
hnjzsyjyj6 小时前
东方博宜OJ 2190:树的重心 ← 邻接表 or 链式前向星
数据结构·链式前向星·树的重心
yaoh.wang8 小时前
力扣(LeetCode) 13: 罗马数字转整数 - 解法思路
python·程序人生·算法·leetcode·面试·职场和发展·跳槽
ChoSeitaku8 小时前
NO15数据结构选择题考点|线性表|栈和队列|串
数据结构
T1ssy8 小时前
布隆过滤器:用概率换空间的奇妙数据结构
算法·哈希算法
hetao17338379 小时前
2025-12-12~14 hetao1733837的刷题笔记
数据结构·c++·笔记·算法
一直都在5729 小时前
数据结构入门:时间复杂度与排序和查找
数据结构
鲨莎分不晴10 小时前
强化学习第五课 —— A2C & A3C:并行化是如何杀死经验回放
网络·算法·机器学习
搞科研的小刘选手10 小时前
【ISSN/ISBN双刊号】第三届电力电子与人工智能国际学术会议(PEAI 2026)
图像处理·人工智能·算法·电力电子·学术会议
拉姆哥的小屋10 小时前
从混沌到秩序:条件扩散模型在图像转换中的哲学与技术革命
人工智能·算法·机器学习
Sammyyyyy10 小时前
DeepSeek v3.2 正式发布,对标 GPT-5
开发语言·人工智能·gpt·算法·servbay