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层

fi=min(fj+(i-j)^2)

根据斜率优化式子

fi=fj+i*i-2*i*j+j*j

fj+j*j=2*i*j+fi-i*i

y=fj+j*j

k=2*i

b=fi-i*i

y=kx-b

当i确定的时候让b最小,fi一定最小

直接维护凸包即可

复制代码
#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;
}
相关推荐
不会代码的小猴26 分钟前
7. JSON
开发语言·c++·笔记·qt·算法·json
怪奇云呼军1 小时前
知识库也会注入指令?闪电智能VoiceAgent 如何防住 Prompt Injection
人工智能·python·算法·云计算·音视频
阿里云大数据AI技术2 小时前
基于 EMR Serverless Ray 实现 Qwen 模型批量推理实践
人工智能·算法·agent
Rambo.xia2 小时前
为什么去马赛克算法,决定了ISP的画质上限
算法·接口隔离原则
Benny_Tang3 小时前
题解:P10230 [COCI 2023/2024 #4] Lepeze
c++·算法
Geek-Chow3 小时前
06 训练管线:数据如何变成权重
人工智能·算法
我变成萤火虫3 小时前
反悔贪心(经典题目讲解)
c++·算法·贪心算法·stl·排序算法·反悔贪心
nike0good3 小时前
April Fools Day Contest 2026 题解
算法·题解·愚人节比赛
_Narcissus_3 小时前
排序算法总结表格
c语言·数据结构·c++·笔记·算法·排序算法·总结