首页 > 其他分享 >2022.10.13 CSP2022 模拟赛三

2022.10.13 CSP2022 模拟赛三

时间:2022-10-13 17:58:00浏览次数:60  
标签:f1 13 pq int ll CSP2022 f2 ans 2022.10

Source: JOI 2018 Final T2-T5

绝了会最后一题不会 T2,麻了。

美术展览

显然的事情:在规定 \(A\) 的值域 \([l,r]\) 之后,对于所有 \(A_i\in[l,r]\),都选进来一定最优。

按 \(A_i\) 从小到大排序后,问题变成了选定一个区间 \([l,r]\),其答案为 \(s_r-s_{l-1}-a_r+a_l\),随便记个前缀 \(\max\) 就行了。

当然我场上脑抽抽了,写了棵线段树。

Code
const int N=5e5+5;
struct node {ll a,b;} t[N];
bool cmp(node x,node y) {return x.a<y.a;}
ll ma[N*4],add[N*4];
void pushadd(int p,ll v) {ma[p]+=v,add[p]+=v;}
void pushdown(int p) {if(add[p]) pushadd(p*2,add[p]),pushadd(p*2+1,add[p]),add[p]=0;}
void pushup(int p) {ma[p]=max(ma[p*2],ma[p*2+1]);}
void build(int p,int l,int r) {
	if(l==r) return ma[p]=t[l].a,void();
	int mid=(l+r)>>1;
	build(p*2,l,mid),build(p*2+1,mid+1,r);
	pushup(p);
}
void update(int p,int l,int r,int x,int y,ll v) {
	if(x<=l&&r<=y) return pushadd(p,v);
	int mid=(l+r)>>1;pushdown(p);
	if(x<=mid) update(p*2,l,mid,x,y,v);
	if(y>mid) update(p*2+1,mid+1,r,x,y,v);
	pushup(p);
}
ll query(int p,int l,int r,int x,int y) {
	if(x<=l&&r<=y) return ma[p];
	int mid=(l+r)>>1;pushdown(p);
	ll ret=0;
	if(x<=mid) ret=max(ret,query(p*2,l,mid,x,y));
	if(y>mid) ret=max(ret,query(p*2+1,mid+1,r,x,y));
	return ret;
}
int main() {
 	int n=read();
 	FOR(i,1,n) t[i].a=read(),t[i].b=read();
 	sort(t+1,t+n+1,cmp);
 	build(1,1,n);
 	ll ans=0;
 	FOR(i,1,n) {
 		update(1,1,n,1,i,t[i].b);
 		ans=max(ans,query(1,1,n,1,i)-t[i].a);
 	}
 	printf("%lld\n",ans);
}

团子制作

我,挺脑瘫的。

注意到互斥的团子串的中间 G 对应的位置一定是对角线:

  R    
  G
RGW

枚举每一条对角线,对对角线从上往下做 DP,具体地,设 \(f_{i,0/1/2}\) 表示第 \(i\) 行 不选/选横的/选竖的 的答案,注意这里的横竖以 G 为中心。

做到 \(O(nm)\)。

Code
const int N=3005;
char ch[N][N];
int f[N][3];
int main() {
    int n=read(),m=read();
    FOR(i,1,n) scanf("%s",ch[i]+1);
    int ans=0;
    FOR(s,2,n+m) {
        memset(f,0,sizeof f);
        int sum=0,i,j;
        for(i=max(1,s-m),j=s-i;i<=n&&j;i++,j--) {
            f[i][0]=max({f[i-1][0],f[i-1][1],f[i-1][2]});
            if(ch[i][j]=='G') {
                if(ch[i-1][j]=='R'&&ch[i+1][j]=='W') f[i][1]=max(f[i][1],max(f[i-1][0],f[i-1][1])+1);
                if(ch[i][j-1]=='R'&&ch[i][j+1]=='W') f[i][2]=max(f[i][2],max(f[i-1][0],f[i-1][2])+1);
            }
            sum=max({sum,f[i][0],f[i][1],f[i][2]});
        }
        ans+=sum;
    }
    printf("%d\n",ans);
}

月票购买

求出 \(S\to T\) 的最短路 DAG,考虑 \(U,V\) 的最短路的变化:

  1. 不经过最短路 DAG,此时的答案可以直接预处理出来。
  2. 经过最短路 DAG,若最短路 DAG 上存在 \(S\to a\to b\to T\),则有一种路径就是 \(U\to a\to b\to T\),以及 \(T\to a\to b\to U\),拓扑排序 DP 即可。

总时间复杂度 \(O(n\log n)\)。

Code
const int N=1e5+5;
vector<pii> G[N];
vi G2[N];
int n,u[2*N],v[2*N],w[2*N],deg[N];
ll dS[N],dT[N],dU[N],dV[N],f1[N],f2[N];
void dijskra(int s,ll *dis) {
    FOR(i,1,n) dis[i]=1e18;
    priority_queue<pair<ll,int> > pq;
    pq.push({0,s}),dis[s]=0;
    while(sz(pq)) {
        int u=pq.top().se;
        ll d=pq.top().fi;
        pq.pop();
        if(-d!=dis[u]) continue;
        for(pii i:G[u]) {
            int v=i.fi,d=i.se;
            if(dis[u]+d<dis[v]) dis[v]=dis[u]+d,pq.push({-dis[v],v});
        }
    }
}
int main() {
    n=read();int m=read(),S=read(),T=read(),U=read(),V=read();
    FOR(i,1,m) {
        u[i]=read(),v[i]=read(),w[i]=read();
        G[u[i]].pb({v[i],w[i]}),G[v[i]].pb({u[i],w[i]});
    }
    dijskra(S,dS),dijskra(T,dT),dijskra(U,dU),dijskra(V,dV);
    ll ans=dU[V];
    FOR(i,1,m) {
        if(dS[u[i]]+w[i]+dT[v[i]]==dS[T]) G2[u[i]].pb(v[i]),deg[v[i]]++;
        if(dS[v[i]]+w[i]+dT[u[i]]==dS[T]) G2[v[i]].pb(u[i]),deg[u[i]]++;
    }
    queue<int> q;
    q.push(S);
    FOR(i,1,n) f1[i]=dU[i],f2[i]=dV[i];
    while(sz(q)) {
        int u=q.front();q.pop();
        ans=min({ans,f1[u]+dV[u],f2[u]+dU[u]});
        for(int v:G2[u]) {
            f1[v]=min(f1[v],f1[u]),f2[v]=min(f2[v],f2[u]);
            deg[v]--;
            if(deg[v]==0) q.push(v);
        }
    }
    printf("%lld\n",ans);
}

毒蛇越狱

听说过套路 trick 就薄纱了。

首先看到这个题,有三个暴力:

  1. 暴力枚举每个 ?,然后累加贡献。
  2. 预处理 \(f_S=\sum_{S'\subseteq S}c_S\),将每个 ? 看成 1,然后对原本的 1 容斥成 1 或者 0
  3. 预处理 \(f_S=\sum_{S\subseteq S'}c_S\),将每个 ? 看成 0,然后对原本的 0 容斥成 1 或者 0

你发现三个暴力分别与 \(c_q,c_1,c_2\) 相关,所以取最小的一个即可做到 \(O(q2^{n/3})\)。

Code
const int MS=1<<21;
int L,Q,f[MS],g[MS];
char c[MS],q[22];
int ans=0;
void dfs1(int dep,int v) {
    if(dep==L) return ans+=c[v]-'0',void();
    if(q[dep]!='?') {
        v|=((q[dep]-'0')<<dep);
        return dfs1(dep+1,v);
    }
    dfs1(dep+1,v);
    v|=(1<<dep);
    dfs1(dep+1,v);
}
void dfs2(int dep,int v,int z) {
    if(dep==L) return ans+=z*g[v],void();
    if(q[dep]!='0') {
        if(q[dep]=='1') v|=1<<dep;
        return dfs2(dep+1,v,z);
    }
    dfs2(dep+1,v,z);
    v|=1<<dep;
    dfs2(dep+1,v,-z);
}
void dfs3(int dep,int v,int z) {
    if(dep==L) return ans+=z*f[v],void();
    if(q[dep]!='1') {
        if(q[dep]=='?') v|=1<<dep;
        return dfs3(dep+1,v,z);
    }
    dfs3(dep+1,v,-z);
    v|=1<<dep;
    dfs3(dep+1,v,z);
}
int main() {
    scanf("%d %d",&L,&Q);
    scanf("%s",c);
    FOR(i,0,(1<<L)-1) f[i]=g[i]=c[i]-'0';
    FOR(i,0,L-1) FOR(j,0,(1<<L)-1) if(!(j&(1<<i))) f[j|(1<<i)]+=f[j];
    FOR(i,0,L-1) FOR(j,0,(1<<L)-1) if(j&(1<<i)) g[j^(1<<i)]+=g[j];
    FOR(i,1,Q) {
        int cq=0,c0=0,c1=0;
        scanf("%s",q);
        FOR(j,0,L-1) {
            if(q[j]=='?') cq++;
            if(q[j]=='0') c0++;
            if(q[j]=='1') c1++;
        }
        reverse(q,q+L);
        int mc=min(cq,min(c0,c1));
        ans=0;
        if(mc==cq) dfs1(0,0);
        else if(mc==c0) dfs2(0,0,1);
        else dfs3(0,0,1);
        printf("%d\n",ans);
    }
}

标签:f1,13,pq,int,ll,CSP2022,f2,ans,2022.10
From: https://www.cnblogs.com/cnyzz/p/16789087.html

相关文章

  • 2022-10-13 uniapp h5端 canvas绘图显示空白
    原因:图片跨域or业务中存在undefined变量,请保证前端img添加了crossorigin="Anonymous"以及后端允许跨域。吐槽:这个问题,真的是。。。。****。嗯,以前做小程序,没出现这种问题......
  • 闲话 22.10.13
    闲话压位trie怎么实现?哪天写一个好于是今天卡了一天的常数然后lyin十分钟给切了没什么要写的诶今天哦对了今天中午换起床歌了瑞苹不如新宝岛谁有什么很诡异的题来......
  • 10月13日内容总结——算法之二分法、三元表达式和各种生成式及匿名函数、部分常见内置
    目录一、算法简介之二分法(需要写的出来)简介什么是算法二分法二、三元表达式什么是三元表本质?三元表达式语法结构三、各种生成式列表生成式字典生成式集合生成式元组生成器(......
  • 10.13
    学习端口安全技术:即802.1x其目的是为了解决局域网用户的接入认证问题其中认证方式分为两种:1.本地认证2.远程集中认证端口接入控制分为两种:基于端口认证-----------端......
  • 【算法】213-每周一练 之 数据结构与算法(LinkedList)
    这是第三周的练习题,原本应该先发第二周的,因为周末的时候,我的母亲大人来看望她的宝贝儿子,哈哈,我得带她看看厦门这座美丽的城市呀。这两天我抓紧整理下第二周的题目和答案,下面......
  • 221013初学C语言笔记
    把Test()强制类型转换成int(*)() 函数指针,再解引用而Test()函数本身就是int型而Test函数名是一个指针。......
  • 《安富莱嵌入式周报》第244期:2021.12.13--2021.12.19
      1、ARM推出的数字信号处理教学资源已经开源分享百度云:​​​https://pan.baidu.com/s/1zkR8h0MmOxd0PB1c1bcgLA​​​  提取码:3qen​​​https://www.arm.com/resou......
  • 《安富莱嵌入式周报》第252期:2022.02.07--2022.02.13
    ​​​​ 本周更新视频教程:STM32H7视频教程第5期:MDK专题,系统介绍MDK的调试,AC5,AC6编译器,RTE开发环境和各种配置项作用(2022-02-13)周报视频版:​​​https://www.bilibili.com......
  • 【JavaScript】13-JS中常见设计模式
    开发中,我们或多或少地接触了设计模式,但是很多时候不知道自己使用了哪种设计模式或者说该使用何种设计模式。本文意在梳理常见设计模式的特点,从而对它们有比较清晰的认知。Ja......
  • SPOJ PHONELST - Phone List | UVA11362 Phone List
    简要题意\(t\)组数据,每组数据给定\(n\)个长度不超过\(10\)的数字串,判断是否有两个字符串\(A\)和\(B\),满足\(A\)是\(B\)的前缀,若有,输出NO,若没有,输出YES。......