首页 > 其他分享 >集训

集训

时间:2024-06-01 16:34:12浏览次数:9  
标签:texttt int void mn long 集训 define

\(\texttt{2024 / 6 / 1 NOIP}\) 模拟赛

\(Rk9\),分数 \(100+40+0+16=156.\)

\(T1\) 直接 \(30min\) 秒了,树剖调都没怎么调。

\(T2\) 上来就发现了一些性质,然后 \(1h\) 后就想出来了正解,然后开调。

但是可持久化线段树太过难写,最后发现还要两棵。

我甚至只知道可持久化线段树的原理,代码忘完了。

然后就写了 \(3h.\)

最后没写出来,但是也接近了。甚至还要维护一堆操作。怒不可遏!

代码 \(60\) 行,我调试 \(30\) 行,醉了。

主席树二分,哼哼哼哼哼!!!

不过刘彻的写法确实很是聪明。


\(A\) 题考虑 \(LCA\) 之后判断,分类讨论即可。证明显然

彻证 ——— 刘彻

\(B\) 题考虑用线段树去掉最小数,直到没有小于 \(0\) 的数。

在删除一个数的时候,把那个数改成 \(+\infty\),然后后面的数集体 \(-1.\)

以此类推。在第二轮的时候,还原线段树。

用栈记录每轮修改的数。

清栈显然是 \(\mathcal{O(1)}\) 的。

程式
#include <bits/stdc++.h>
#define ll long long
#define ls (u<<1)
#define rs (u<<1|1)
#define lson ls,l,mid
#define rson rs,mid+1,r
#define mid ((l+r)>>1)
#define file "book"
using namespace std;
const int N=5e5+10,inf=0x3f3f3f3f;
int n,d,cnt,a[N],st[N];
struct sgt{
	int mn[N],ps[N],tg[N];
	inline void pu(int u){if(mn[ls]>mn[rs])mn[u]=mn[rs],ps[u]=ps[rs];else mn[u]=mn[ls],ps[u]=ps[ls];}
	inline void p(int u,int x){mn[u]+=x,tg[u]+=x;}
	inline void pd(int u){if(tg[u])p(ls,tg[u]),p(rs,tg[u]),tg[u]=0;}
	inline void upd(int u,int l,int r,int L,int R,int k){
		if(R<L)return;
		if(L<=l&&r<=R)return p(u,k);pd(u);
		if(L<=mid)upd(lson,L,R,k);
		if(R> mid)upd(rson,L,R,k);pu(u);
	}
	inline void bd(int u,int l,int r){
		if(l==r)return ps[u]=l,mn[u]=a[l],void();
		bd(lson),bd(rson),pu(u);
	}
}t;
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>d>>n;
	for(int i=1;i<=n;++i)cin>>a[i];
	t.bd(1,1,n);
	for(int i=1;i<=n+1;++i){
		int top=0;
		if(i==n+1)return cout<<-1<<"\n",0;
		for(;t.mn[1]<=0;){
			int p=t.ps[1];
			t.upd(1,1,n,p+1,n,-1),t.upd(1,1,n,p,p,inf),st[++top]=p,++cnt;
		}
		if(cnt==n)return cout<<i<<"\n",0;
		for(int j=1;j<=top;++j)t.upd(1,1,n,st[j]+1,n,1);
		t.upd(1,1,n,1,n,-top);
	}
	return 0;
}

\(\texttt{2024 / 5 / 2 NOIP}\) 模拟赛

\(90+85+0+45= 220\)

本来应该 \(100+100+15+45=260\) 的,这样的成绩是我彩笔导致的。

\(A\) 题前缀异或桶,开考半个小时就将之秒掉了,但是没开 \(\texttt{long long}\) 挂掉了 \(10pts.\) 非常生气。

\(\texttt{B}\)

思维题。

给一个 \(a_i(i=1,2,3,\cdots,n).\)

进行无数次下面两种操作:

  1. 在端点处删除一个数

  2. 在不是端点处将 \(a_{i-1},a_i,a_{i+1} \rightarrow a_{i-1}+a_{i+1}\)

直到只剩下一个数。最大化这个数的值并且操作次数最小。输出这两个值。

有发现:

在进行一次 \(2\) 操作之后,如果将池子里面的数重新编号,那么新加进来的数是 \(i-1\) 号,往后两位应该是 \(i,i+1\)。

显然奇偶性没有发生改变。那么考虑对奇偶拆开统计。

如果是负数不要,否则加进来。

只要把偶数位置上的正数求和,把奇数位置上的正数求和,得到 \(R_1,R_2\),最后的答案就是 \(\max\{R_1,R_2\}.\)

操作次数:只要分开来统计一下就好了。

最后要特判一下全是负数的情况。取绝对值最小的那个负数就好了。

复杂度 \(\mathcal{O(n)}.\)

\(\texttt{C}\)

有两个序列 \(\{a_n\},\{b_n\}.\) 两个序列都是单调不降的。要让 \(\{a\}\) 变成 \(\{b\}\),可以将 \(a \rightarrow a+x\),代价是 \(x^2\)。在 \(\{a\}\) 时时刻刻单调不降的前提下使代价最小。

发现最后一句话的限制实际上是没有任何用处的。原因是可以调换增减顺序。

又发现我们所关注的不见得是 \(a_i,b_i\) ,而是差值 \(|a_i-b_i|.\)

要将 \(a_i\) 变作 \(b_i\) 并且消耗 \(m\) 刀,可以考虑平均下来每次的代价。

计算如下:

\[f(x,y)=\left[\dfrac{x}{y}\right]^2(x\bmod y) + \left[\dfrac{x}{y}+1\right]^2(y-x\bmod y) \]

显然,\(f(x,y)\) 是随着 \(y\) 的增大而减小的。但是每一刀放在每个数身上减小是不同的。所以可以考虑用堆来维护。

思路类似于 \(P5283\) [十二省联考 2019] 异或粽子,其实还是比较巧妙的

程式
#include <bits/stdc++.h>
#define int long long
#define mod 998244353
#define file "attend"
using namespace std;
typedef __int128 lint;
typedef pair<lint,int> pii;
typedef priority_queue<pii> Pq;
Pq pq;
const int N=1e5+10;
lint f(int x,int y){ return (lint)(x/y)*(x/y)*(y-x%y)+(lint)(x/y+1)*(x/y+1)*(x%y); }
int n,m;
int cnt;
int a[N],b[N],v[N],p[N];
lint ans;
signed main(){
	freopen(file ".in","r",stdin);
	freopen(file ".out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	cin>>n>>m;
	for(register int i=1;i<=n;++i) cin>>a[i];
	for(register int i=1;i<=n;++i) cin>>b[i],v[i]=abs(a[i]-b[i]) %mod;
	for(register int i=1;i<=n;++i) cnt+=(a[i]!=b[i]),ans=ans+v[i]*v[i] %mod,p[i]=1;
	if(m<cnt) return puts("-1"),0;
	m-=cnt;
	for(int i=1;i<=n;++i) if(v[i]>=2ll) pq.push(make_pair(f(v[i],1ll)-f(v[i],2ll),i));
	while(!pq.empty()&&m){
		m--;
		int x=pq.top().second;
		ans=(ans-pq.top().first) %mod;
		p[x]++,	pq.pop();
		if(p[x]<v[x]) pq.push(make_pair((int)f(v[x],p[x])-(int)f(v[x],p[x]+1ll),x));
	}
	return printf("%lld",(int)((ans+mod) %mod)),0;
}

\(\texttt{2024 / 5 / 1 NOIP}\) 模拟赛

\(T1\) 觉得很弱小的字符串, \(Trick\) 也比较明显。

\(\texttt{T2}\)

神仙题。

输入 \(n\) 个数 \(\{a\}\),问在 \(\{a\}\) 中,每个 \(a_i\) 至多可以减去 \(k\)(不能减成 \(0\) ),至多删去 \(f\) 个数,求最后合法的公约数 \(g\) 的全部方案。

60

考虑如果 \(g\) 是 \(a_i\) 的约数,那么 \(a_i-k=cg\ (c\in N).\)

而 \(k\) 已经给定,所以当且仅当 \(cg \leq a_i \leq cg+k\) 才行,也就是 \(a_i \bmod g \leq c.\)

计算 \(a_i\bmod g >c\) 这样的 \(a_i\) 数量,最后与 \(f\) 比较就好了。

100

考虑一种可以快速统计值出现在 \(l,r\) 的数的个数的方法。显然可以桶 \(+\) 前缀和处理。

而枚举提到的 \(d=cg\) ,然后统计出现在 \(d+k+1,d+g-1\) 的数的个数,最后与 \(f\) 比较就好了。

而 \(d\) 枚举次数出现在 \(n/1,n/2,n/3,\cdots,n/n\),加起来是调和级数,最后复杂度明显是 \(\mathcal{O[T(\alpha\log \alpha+n)]}.\) 足以通过本题。

程式
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e5+10;
int T,n,k,f,maxi=0,dlt,ans;
int a[N],t[N],q[N];
inline int re(void){
	int res=0; char ch=0;
	while(!isdigit(ch)) ch=getchar();
	while(isdigit(ch)) res=(res<<1)+(res<<3)+(ch^48), ch=getchar();
	return res;
}
int main(){
	freopen("tsuki.in","r",stdin);
	freopen("tsuki.out","w",stdout);
	T=re();
	while(T--){
		maxi=0;
		memset(t,0,sizeof t);
		memset(q,0,sizeof q);
		n=re(),k=re(),f=re();
		for(int i=1;i<=n;++i) a[i]=re(),t[a[i]]++,maxi=max(maxi,a[i]);
		for(int i=1;i<=maxi;++i) q[i]=q[i-1]+t[i];
		for(int g=1;g<=maxi;++g){
			dlt=q[g-1];
			for(int i=g;dlt<=f&&i+k+1<=maxi;i+=g) {
				int l=i+k+1,rgt=min(maxi,i+g-1);
				if(l<=rgt) dlt+=q[rgt]-q[l-1];
			}
			if(dlt<=f) printf("%d ",g);
		}
		puts("");
	}
	return 0;
}

觉得这种东西在考场上根本不能想到耶。

标签:texttt,int,void,mn,long,集训,define
From: https://www.cnblogs.com/chihirofujisaki/p/18226077/NOIP_NOI

相关文章

  • tdog集训-朱家炜
    TDOG集训define\(|s|:字符串s的长度\)\(fac_x:x的因数个数\)Day1T1.乘积累加和已完成Question:求C(n,0)*C(n,0)+C(n,1)*C(n,1)…+C(n,n)*C(n,n),对\(10^9+7\)取模Analysis:数学原式可通过二项式定理转化成求\(C_{2n}^n\bmod1e9+7\)。Solution:预处理阶乘和逆元。剩......
  • [国家集训队] Tree I
    借助这道题目把wqs二分讲明白考虑如下一个问题:现在一共有若干个物品,物品被分成两组,现在从中选出若干个物品,但是题目会给出某种限制(也就是在这种限制条件下,物品的选择不是随意的,所有选择集合中,只有一些集合符合题目给出的限制,这样的集合才可以被选择),这种限制只跟物品本身有关而跟......
  • 2024 年春节集训 _ 第四课 - 网络流
    考虑\(EK\)算法求解最大流。每次找一条最小剩余流量\(d>0\)的\(s\rightsquigarrowt\)的路径。然后对之流下\(d\)的水。这个操作我们称之为增广,所找到的这条路径叫做增广路。一直增广到不存在任何增广路为止。发现这样的贪心策略有时是错误的。考虑反悔。连一条反边,反......
  • 小集训 - 3
    这个世界就是一个巨大的问号5.11下午继续被AC自动机的板题切感觉可能会一点AC自动机的dp了然后写了依托答辩这小自信一下子就起来了也一下子就下来了(重点在时间)淦,对着题解贺都没贺明白......
  • [国家集训队] happiness 题解
    发现可以做如下建图:对于前两组输入,从\(s\)向所有代表学生的点连一条边,容量为其学习文科的喜悦值;从所有代表学生的点向\(t\)连一条边,容量为其学习理科的最大值。对于后四组输入,建两个点\(x,y\),从\(s\)向\(x\),从\(y\)向\(t\)分别连容量为相邻两人同时学文/理时额......
  • QBXT五一集训DAY4笔记
    \(Day\)\(4\)图论图论主要分为\(4\)个方面1.最短路2.二分图匹配3.生成树4.强连通(这个超纲了,不讲)在介绍完理论知识后,我们会逐一讨论它们图图是由点和边构成的边又分为有向边和无向边,因此图可以分为有向图和无向图无向图的度指的是一个点连了多少条边有向图的入度指的......
  • [国家集训队] Crash的数字表格 / JZPTAB
    题目所求即\[\sum_{i=1}^n\sum_{j=1}^m\frac{ij}{gcd(i,j)}\]这里没有出现\([gcd(x,y)=1]\),所以我们枚举\(gcd\)的值来硬凑,原式就等于\[\sum_{d=1}^{min(n,m)}\sum_{i=1}^n\sum_{j=1}^m\frac{ij}{gcd(i,j)}[gcd(i,j)=d]\]为了出现\([gcd(i,j)=1]\),直接将\(i,j\)变成\(d\)的倍......
  • 2024牛客五一集训-1
    CoffeeChicken基本思路:f[i]表示s[i]的字符串长度即f[i]=f[i-2]+f[i]solve(n,k)表示s[n]中第k个字符当n<=2时,直接返回答案当n>2时,k>f[i-2]时solve(n-1,k-f[n-2]);说明要找的字符在前一天中,也就是不在前两天的数据范围之内,因此直......
  • QBXT五一集训DAY3笔记
    \(Day\)\(3\)位运算位运算包含了五个运算符,分别是:&与只有两个对应位都为\(1\)时才为\(1\)|或只要两个对应位中有一个\(1\)时就为\(1\)^异或只有两个对应位不同时才为\(1\)<<左移如\(n<<i\)表示将\(n\)的二进制向左移动\(i\)位,等价于\(n*2^i\)>......
  • 集训 4 & 模拟 5
    集训4&模拟5有点唐简单,所以一起写了(其实是因为之前懒得写)集训4:T1模拟,赛时不删调试保龄了。T2显然贪心T3发现显然要两两互质,有因为父比子小,所以方案数就是将\(\varphi\)乘起来(甚至都不需要线性筛)T4meetinmiddle板子。模拟5T1特殊字符串显然有\(n^2\)......