首页 > 其他分享 >CSP2024 前集训:csp-s模拟10

CSP2024 前集训:csp-s模拟10

时间:2024-10-08 21:34:41浏览次数:8  
标签:10 unlocked int void CSP2024 Tp read inline csp

前言

image

image

T2 赛时不会,T3 没有想到移项遂打了个背包得 \(50pts\),T4 又放回滚莫队板子,结过开太晚了没打完,以后板子麻烦放靠前点谢谢。

T1

需要线性基思想,听 5k 讲完貌似懂了,但是学了再回来补吧。

T2

首先选择一个度数不是 \(1\) 的点当根。

对于一个非叶子节点 \(p\) 被扫到有两种情况:

  1. 两个叶子 \(x,y\) 且 \(lca(x,y)=p\)。
  2. 子树内一个叶子 \(x\) 去连接子树外的一个叶子 \(y\)。

对于第一种情况,两个叶子产生一次贡献,此时这两个叶子就可以消去 \(1\) 了。

对于第二种情况,一个叶子即可产生一次贡献,无法消去,故此不放另 \(p\) 集成 \(son_p\) 的贡献继续递归。

\(f_p\) 表示 \(p\) 集成或叶子本身存在的贡献,因为 \(p\) 最多只能被扫 \(a_p\) 遍,所以当 \(sum=\sum\limits_{x\in son_p}f_x>a_p\) 时就需要一些情况一,设情况一个数为 \(y\),则有 \(y=sum-a_p\),那么有 \(f_p=sum-2y\),发现这些都是定值,DP 就可以转移了。

那么如何判无解,每两个贡献才能凑一个操作一,同时一个贡献最多的叶子节点 \(x\) 只能凑够 \(sum-f_x\) 个操作一,故需同时满足:

  • \(0\le f_p\le a_p\)
  • \(\dfrac{sum}{2}\ge y\)
  • \(sum-\max\limits_{x\in son_p}f_x\ge y\)
  • \(f_{rt}=0\)
点击查看代码
#include<bits/stdc++.h>
#define ll long long 
#define endl '\n'
#define sort stable_sort
#define pb push_back
using namespace std;
const int N=1e5+10;
template<typename Tp> inline void read(Tp&x)
{
	x=0;register bool z=true;
	register char c=getchar_unlocked();
	for(;!isdigit(c);c=getchar_unlocked()) if(c=='-') z=0;
	for(;isdigit(c);c=getchar_unlocked()) x=(x<<1)+(x<<3)+(c^48);
	x=(z?x:~x+1);
}
template<typename T,typename ...Tp> inline void read(T &x,Tp &...y){read(x);read(y...);}
template<typename Tp> inline void wt(Tp x){if(x>9)wt(x/10);putchar_unlocked((x%10)+'0');}
template<typename Tp> inline void write(Tp x){if(x<0)putchar_unlocked('-'),x=~x+1;wt(x);}
template<typename T,typename ...Tp> inline void write(T x,Tp ...y){write(x);putchar_unlocked(' ');write(y...);}
int n,rt,a[N],d[N],f[N]; vector<int>e[N];
bool dfs(int x,int t)
{
	if(d[x]==1) return f[x]=a[x],1;
	int mx=0,sum=0;
	for(int y:e[x]) if(y!=t) 
	{
		if(!dfs(y,x)) return 0;
		sum+=f[y],mx=max(mx,f[y]);
	}
	int y=sum-a[x]; f[x]=sum-(y<<1);
	return (f[x]<=a[x]&&min(sum>>1,sum-mx)>=y&&!f[rt]);
}
signed main()
{
	freopen("tree.in","r",stdin),freopen("tree.out","w",stdout);
	read(n); for(int i=1;i<=n;i++) read(a[i]);
	if(n==2) puts(a[1]==a[2]?"YES":"NO"),exit(0);
	for(int i=1,x,y;i<n;i++) read(x,y),d[x]++,d[y]++,e[x].pb(y),e[y].pb(x);
	for(int i=1;i<=n;i++) if(d[i]!=1) {rt=i; break;}
	puts(dfs(rt,0)?"YES":"NO");
}

T3

  • 部分分 \(50pts\):\(O(2^n)\) 爆搜加 \(O(n^2v)\) 背包,\(v\) 是 \(a\) 的值域。

  • 正解:

    若存在 \(k\le a_i\le 2k\),等价于 \(\lceil\frac{a_i}{2}\rceil\le k\le a_i\),那么 \(k\) 对应了一个区间 \([\lceil\frac{a_i}{2}\rceil,a_i]\)。

    若再加入一个 \(a_j\le a_i\),那么有 \(k\) 对应区间 \([\lceil\frac{a_i+a_j}{2}\rceil,a_i+a_j]\),显然好有 \(\lceil\frac{a_i}{2}\rceil\le \lceil\frac{a_i+a_j}{2}\rceil\le a_i\le a_i+a_j\),不难发现 \([\lceil\frac{a_i}{2}\rceil,a_i]\) 和 \([\lceil\frac{a_i+a_j}{2}\rceil,a_i+a_j]\) 必定存在交际,那么两者取并就是 \(k\) 的最终范围 \([\lceil\frac{a_i}{2}\rceil,a_i+a_j]\)。

    再将其扩展到 \(n\) 个数,再做前缀和处理,会得到 \(n\) 个左右端点均单调的区间,取并即可。

    点击查看代码
    #include<bits/stdc++.h>
    #define ll long long 
    #define endl '\n'
    #define sort stable_sort
    #define fi first
    #define se second
    #define mkp make_pair
    using namespace std;
    const int N=1e5+10;
    template<typename Tp> inline void read(Tp&x)
    {
    	x=0;register bool z=true;
    	register char c=getchar_unlocked();
    	for(;!isdigit(c);c=getchar_unlocked()) if(c=='-') z=0;
    	for(;isdigit(c);c=getchar_unlocked()) x=(x<<1)+(x<<3)+(c^48);
    	x=(z?x:~x+1);
    }
    template<typename T,typename ...Tp> inline void read(T &x,Tp &...y){read(x);read(y...);}
    template<typename Tp> inline void wt(Tp x){if(x>9)wt(x/10);putchar_unlocked((x%10)+'0');}
    template<typename Tp> inline void write(Tp x){if(x<0)putchar_unlocked('-'),x=~x+1;wt(x);}
    template<typename T,typename ...Tp> inline void write(T x,Tp ...y){write(x);putchar_unlocked(' ');write(y...);}
    int n,a[N]; ll ans,now,sum[N]; pair<int,ll>pos[N];
    signed main()
    {
    	freopen("buy.in","r",stdin),freopen("buy.out","w",stdout);
    	read(n); for(int i=1;i<=n;i++) read(a[i]);
    	sort(a+1,a+1+n); for(int i=i;i<=n;i++) sum[i]=sum[i-1]+a[i];
    	for(int i=1;i<=n;i++) pos[i]=mkp(a[i]+1>>1,sum[i]);
    	for(int i=1;i<=n;i++)
    		ans+=pos[i].se-max(now,1ll*pos[i].fi)+1,now=pos[i].se+1;
    	write(ans);
    }
    

T4

  • 部分分 \(50pts\):普通莫队加线段树维护,\(O(n\sqrt n\log(n))\),常数巨大过不去。

  • 正解:

    回滚莫队板子,套链表为 \(O(n\sqrt n)\),套正常可撤销并查集为常数小的 \(O(n\sqrt n\log(n))\)。

    点击查看代码
    #include<bits/stdc++.h>
    #define ll long long 
    #define endl '\n'
    #define sort stable_sort
    using namespace std;
    const int N=1e5+10;
    template<typename Tp> inline void read(Tp&x)
    {
    	x=0;register bool z=true;
    	register char c=getchar_unlocked();
    	for(;!isdigit(c);c=getchar_unlocked()) if(c=='-') z=0;
    	for(;isdigit(c);c=getchar_unlocked()) x=(x<<1)+(x<<3)+(c^48);
    	x=(z?x:~x+1);
    }
    template<typename T,typename ...Tp> inline void read(T &x,Tp &...y){read(x);read(y...);}
    template<typename Tp> inline void wt(Tp x){if(x>9)wt(x/10);putchar_unlocked((x%10)+'0');}
    template<typename Tp> inline void write(Tp x){if(x<0)putchar_unlocked('-'),x=~x+1;wt(x);}
    template<typename T,typename ...Tp> inline void write(T x,Tp ...y){write(x);putchar_unlocked(' ');write(y...);}
    int n,m,t,res,a[N],b[N],pos[N],len[N],ans[N]; stack<pair<int,int> >sl,sr;
    struct aa {int id,l,r;}e[N];
    void add(int x,stack<pair<int,int> >&s)
    {
    	int pre=len[x-1],suf=len[x+1];
    	s.emplace(x-pre,len[x-pre]),s.emplace(x+suf,len[x+suf]);
    	res=max(res,len[x-pre]=len[x+suf]=pre+suf+1);
    }
    void clear(stack<pair<int,int> >&s) 
    {while(!s.empty()) len[s.top().first]=s.top().second,s.pop();}
    signed main()
    {
    	freopen("ants.in","r",stdin),freopen("ants.out","w",stdout);
    	read(n,m),t=sqrt(n);
    	for(int i=1;i<=n;i++) read(a[i]),pos[i]=(i-1)/t+1;
    	for(int i=1,l,r;i<=m;i++)
    	{
    		read(l,r),e[i]={i,l,r};
    		if(pos[l]==pos[r])
    		{
    			for(int i=l;i<=r;i++) add(a[i],sl);
    			ans[i]=res,res=0,clear(sl);
    		}
    	}
    	sort(e+1,e+1+m,[](aa a,aa b){return pos[a.l]==pos[b.l]?a.r<b.r:a.l<b.l;});
    	for(int i=1,j=1,l,r;j<=pos[n];j++)
    	{
    		int bl=min(n+1,j*t+1); r=(l=bl)-1,res=0,clear(sr);
    		for(;pos[e[i].l]==j;i++) if(pos[e[i].l]!=pos[e[i].r])
    		{
    			while(r<e[i].r) add(a[++r],sr);
    			int old=res;
    			while(l>e[i].l) add(a[--l],sl);
    			ans[e[i].id]=res,res=old,l=bl,clear(sl);
    		}
    	}
    	for(int i=1;i<=m;i++) write(ans[i]),puts("");
    }
    

标签:10,unlocked,int,void,CSP2024,Tp,read,inline,csp
From: https://www.cnblogs.com/Charlieljk/p/18453095

相关文章

  • 2024-10-8
    标签之文本标签列表标签之有序列表列表标签之无序列表表格标签实操点击查看代码<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0......
  • CSP 模拟 40
    A挤压看到异或首先拆位,看到统计期望的次幂考虑二项式定理或者组合意义。发现二项式定理不会,然后思考平方式子拆开,\(s_i\)表示\(2^i\),\(x^2=\sum_{i=1}s_i\sum_{j=1}s_j=\sum_{i=1}\sum_{j=1}s^{i+j}\),然后设\(f_{i,j,0/1,0/1}\)表示到当前数异或之后,第\(i\)位为\(0/1\),......
  • 国庆结束第一天-2024/10/8
    今天上午,我们进行了工程实训,下午我们上了uml统一建模语言,老师讲了用例图的知识点让我们自己选择一个系统去完成用例图的制作,用户观点并非系统观点用例图的组成元素:参与者,用例,用例图之间的关系一些java的知识点throw和throws抛出:告诉调用者程序出错了捕获:不让......
  • 20241008-坠机
    因为家长的要求,不能在网上说自己去【数据删除】了,所以这里用坠机代替。因为我用这个词的意义应该我的熟人都知道,然后一些相关的人物可能也会替换一下,虽然可能会使得场景显得不是那么严肃而是滑稽了。总之就是令人心旷神怡的形式主义。同时我还加了一个合集,因为接下来我大概每周都......
  • 推荐!专业Substance 3D Painter v10.解锁版下载及安装 (3D绘画软件)
    AdobeSubstance3DPainter简称Pt,是一款由adobe公司新研发的3D绘画软件。Substance3DPainter具有前所未有的功能和工作流程改进,使为3D资产创建纹理变得比以往更容易。具体安装方式如下:下载地址:Substance3DPainterv10.解锁版下载1、解压后点击如下图运行2、选择安装......
  • [CSP-S 2019 江西] 网格图
    算法暴力建图直接跑Kruskal,显然能通过\(64pts\)的点正解分析Kruskal的复杂度发现比较边权非常的浪费,很显然是不必要的并查集求环路也浪费了网格图的性质考虑优化把每一条边看做一个整体,整体比较只需要\(O((n+m)\log(n+m))\)问题是这样比较之后正确性如......
  • 10.8
    不知道为什么学习数学相关的东西总会思绪淤塞,心情烦躁,于是狂贺不止跑来写总结。第\(2\)次$NOIP$模拟赛进步了整整\(38pts\),增幅到了\(30.4%\),来到了惊人的\(163pts\)!实际得分\(0+100+63+0\)。A.兰亭序无关风月我题序等你回悬笔一绝那岸边浪千叠情字何解怎......
  • 【RAG论文精读3】RAG论文综述1(2312.10997)-第1部分
    收录于我的专栏:AI修炼之路简介论文中英文名Retrieval-AugmentedGenerationforLargeLanguageModels:ASurvey面向大型语言模型的检索增强生成:综述论文地址arxiv地址:https://arxiv.org/abs/2312.10997精读理由这篇综述论文对RAG在大型语言模型中的应用进行了......
  • 10月8日记录
    制作了一个验证码生成器;点击查看代码importjavax.swing.*;importjava.awt.*;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjava.util.Random;publicclassSimpleMathQuizextendsJFrame{privatestaticfinalintNUM_QUEST......
  • 10.8日
    在今日早上的工程实训中的电工基础实训中学习了不同的触电事故:电击和电伤,对于应对触电事故的措施和急救措施。Js是一种弱编程语言,其中对于声明变量,变量的数据类型有Number,String、boolean、undefined、null等,变量的数据类型取决于变量的值。其中声明变量有两种,let声明在目前使用......