首页 > 其他分享 >暑假集训CSP提高模拟12

暑假集训CSP提高模拟12

时间:2024-07-31 17:20:11浏览次数:8  
标签:线段 12 gcd 集训 T4 差分 CSP ans ll

暑假集训CSP提高模拟12

\(T1\) P171. 黑客 \(40pts\)

  • 将式子进行二维差分。

  • 考虑枚举 \(\frac{i+j}{\gcd(i,j)}=t\) ,并统计它能对答案产生的贡献。令 \(\gcd(i,j)=1\) ,这样的话才会不重不漏。

  • 推式子,有 \(\begin{aligned} &\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}[\frac{i+j}{\gcd(i,j)} \le 999] \times \frac{i+j}{\gcd(i,j)} \\ &=\sum\limits_{t=2}^{\min(n+m,999)}\sum\limits_{i=max(t-m,1)}^{\min(t-1,n)}[\gcd(i,t-i)=1] \sum\limits_{k=1}^{\min(\left\lfloor \frac{n}{i} \right\rfloor,\left\lfloor \frac{m}{t-i} \right\rfloor)}t \end{aligned}\) 。

    点击查看代码
    const ll p=1000000007;
    ll gcd(ll a,ll b)
    {
    	return b?gcd(b,a%b):a;
    }
    ll ask(ll n,ll m)
    {
    	ll ans=0;
    	for(ll t=2;t<=min(n+m,999ll);t++)
    	{
    		for(ll i=max(t-m,1ll);i<=min(t-1,n);i++)
    		{
    			if(gcd(i,t-i)==1)
    			{
    				ans=(ans+t*min(n/i,m/(t-i))%p)%p;
    			}
    		}
    	}
    	return ans;
    }
    int main()
    {
    	ll a,b,c,d;
    	cin>>a>>b>>c>>d;
    	cout<<(ask(b,d)-ask(a-1,d)-ask(b,c-1)+ask(a-1,c-1)+2*p)%p<<endl;
    	return 0;
    }
    

\(T2\) P133. 密码技术 \(0pts\)

  • 原题: [ARC107C] Shuffle Permutation

  • 不难发现,行的交换并不会影响列的交换,列的交换并不会影响行的交换。

  • 暴力处理出能互相交换的行和列,并将其看作连通块,并查集维护大小。

  • 最终,各连通块大小的阶乘的乘积即为所求。

    点击查看代码
    const ll p=998244353;
    ll a[100][100],jc[100];
    struct DSU
    {
    	ll fa[100],siz[100];
    	void init(ll n)
    	{
    		for(ll i=1;i<=n;i++)
    		{
    			fa[i]=i;
    			siz[i]=1;
    		}
    	}
    	ll find(ll x)
    	{
    		return (fa[x]==x)?x:fa[x]=find(fa[x]);
    	}
    	void merge(ll x,ll y)
    	{
    		x=find(x);
    		y=find(y);
    		if(x!=y)
    		{
    			fa[y]=x;
    			siz[x]+=siz[y];
    			siz[y]=0;
    		}
    	}
    }D;
    bool check1(ll x,ll y,ll n,ll k)
    {
    	for(ll i=1;i<=n;i++)
    	{
    		if(a[x][i]+a[y][i]>k)
    		{
    			return false;
    		}
    	}
    	return true;
    }
    bool check2(ll x,ll y,ll n,ll k)
    {
    	for(ll i=1;i<=n;i++)
    	{
    		if(a[i][x]+a[i][y]>k)
    		{
    			return false;
    		}
    	}
    	return true;
    }
    int main()
    {
    	ll n,k,ans=1,i,j;
    	cin>>n>>k;
    	jc[0]=1;
    	for(i=1;i<=n;i++)
    	{
    		jc[i]=jc[i-1]*i%p;
    		for(j=1;j<=n;j++)
    		{
    			cin>>a[i][j];
    		}
    	}
    	D.init(n);
    	for(i=1;i<=n;i++)
    	{
    		for(j=i+1;j<=n;j++)
    		{
    			if(check1(i,j,n,k)==true)
    			{
    				D.merge(i,j);
    			}
    		}
    	}
    	for(i=1;i<=n;i++)
    	{
    		ans=ans*jc[D.siz[i]]%p;
    	}
    	D.init(n);
    	for(i=1;i<=n;i++)
    	{
    		for(j=i+1;j<=n;j++)
    		{
    			if(check2(i,j,n,k)==true)
    			{
    				D.merge(i,j);
    			}
    		}
    	}
    	for(i=1;i<=n;i++)
    	{
    		ans=ans*jc[D.siz[i]]%p;
    	}
    	cout<<ans<<endl;
    	return 0;
    }
    

\(T3\) P151. 修水管 \(0pts\)

\(T4\) P163. 货物搬运 \(20pts\)

  • 原题: CF455D Serega and Fun

  • 观察到 \(a_{i},k \le n\) 且强制在线,启示我们从值域入手。

  • 分块

    • 考虑分块,设 \(cnt_{i,j}\) 表示 \(j\) 在 \(i\) 中出现的次数,整块仅有首尾两个元素发生了改变,散块则需要实现任意位置插入和删除,首段散块多了一个元素,尾端散块少了一个元素,使用 dequelist 维护即可。
    • 块长取 \(\sqrt{n}\) 。
    点击查看代码
    int a[100010],pos[100010],L[330],R[330],cnt[330][100010],klen,ksum;
    deque<int>q[330];
    void init(int n)
    {
    	klen=sqrt(n);
    	ksum=n/klen;
    	for(int i=1;i<=ksum;i++)
    	{
    		L[i]=R[i-1]+1;
    		R[i]=R[i-1]+klen;
    	}
    	if(R[ksum]<n)
    	{
    		ksum++;
    		L[ksum]=R[ksum-1]+1;
    		R[ksum]=n;
    	}
    	for(int i=1;i<=ksum;i++)
    	{
    		for(int j=L[i];j<=R[i];j++)
    		{
    			pos[j]=i;
    			q[i].push_back(a[j]);
    			cnt[i][a[j]]++;
    		}
    	}
    }
    void update(int l,int r)
    {
    	if(pos[l]==pos[r])
    	{
    		ll x=q[pos[l]][r-L[pos[l]]];
    		q[pos[l]].erase(q[pos[l]].begin()+(r-L[pos[l]]));
    		q[pos[l]].insert(q[pos[l]].begin()+(l-L[pos[l]]),x);
    	}
    	else
    	{
    		q[pos[l]].insert(q[pos[l]].begin()+(l-L[pos[l]]),q[pos[r]][r-L[pos[r]]]);
    		cnt[pos[l]][q[pos[r]][r-L[pos[r]]]]++;
    		cnt[pos[r]][q[pos[r]][r-L[pos[r]]]]--;
    		q[pos[r]].erase(q[pos[r]].begin()+(r-L[pos[r]]));
    		for(int i=pos[l]+1;i<=pos[r];i++)
    		{
    			q[i].push_front(q[i-1].back());
    			cnt[i][q[i-1].back()]++;
    			cnt[i-1][q[i-1].back()]--;
    			q[i-1].pop_back();
    		}
    	}
    }
    int query(int l,int r,int k)
    {
    	int ans=0;
    	if(pos[l]==pos[r])
    	{
    		for(int i=l;i<=r;i++)
    		{
    			ans+=(q[pos[l]][i-L[pos[l]]]==k);
    		}
    	}
    	else
    	{
    		for(int i=l;i<=R[pos[l]];i++)
    		{
    			ans+=(q[pos[l]][i-L[pos[l]]]==k);
    		}
    		for(int i=pos[l]+1;i<=pos[r]-1;i++)
    		{
    			ans+=cnt[i][k];
    		}
    		for(int i=L[pos[r]];i<=r;i++)
    		{
    			ans+=(q[pos[r]][i-L[pos[r]]]==k);
    		}
    	}
    	return ans;
    }
    int main()
    {
    	int n,m,pd,l,r,k,ans=0,i;
    	cin>>n;
    	for(i=1;i<=n;i++)
    	{
    		cin>>a[i];
    	}
    	init(n);
    	cin>>m;
    	for(i=1;i<=m;i++)
    	{
    		cin>>pd>>l>>r;
    		l=(l+ans-1)%n+1;
    		r=(r+ans-1)%n+1;
    		if(l>r)
    		{
    			swap(l,r);
    		}
    		if(pd==1)
    		{
    			update(l,r);
    		}
    		else
    		{
    			cin>>k;
    			k=(k+ans-1)%n+1;
    			ans=query(l,r,k);
    			cout<<ans<<endl;
    		}
    	}
    	return 0;
    }
    

总结

  • 赛时历程:溜了一眼题后, \(T1,T2,T3\) 都不太可做, \(T4\) 一眼数据结构且有思路。开场直接开 \(T4\) ,敲暴力时因为不会用 vectoreraseinsert 单独又开了个程序实验了一下,想了 \(1h\) 就想出了线段树套平衡树的高级做法,莫名自信告诉我区间修改可以差分,区间查询实际上是单点查询(查询区间和查询点搞混了),主席树代码并不长,一会儿就码完了,调代码时因为终端有延迟导致以为大样例过了的代码其实没过,中间有一份代码是过大样例了的但跑了 \(2.3s\) ,卡常和调空间(空间很紧张)途中测了发小样例直接 \(WA\) 了,然后就开始四处乱调。一直持续到 \(9:40\) ,突然意识到差分的做法是假的,此刻我主席树的复杂度甚至不如暴力,赛后发现交的代码 \(RE\) 了,心态崩了。然后开始写树套树,因还觉得差分有一定正确性所以先写的树状数组套主席树,发现没过样例后开始写线段树套主席树,觉得 \(O(n \log^{2}n)\) 的时间复杂度加上主席树的巨大常数估计过不去,这还没有算空间复杂度的影响。 \(10:30\) 弃了 \(T4\) ,把暴力交上去了。然后开始写 \(T1,T2,T3\) 的部分分,部分分不会打后又滚回去打 \(T4\) 的线段树套主席树了,发现还要线段树合并,这样的话空间复杂度就假了,心态又崩了。尝试写 \(T1\) ,推出式子后仅剩 \(3\min\) 了。赛后发现 \(T3\) 读假题了。
  • \(T1\)
    • 由于惯性思维,直接就往莫反上想了,最后才想到利用 \(x+y \in [0,999]\) 的性质。
  • \(T2\)
    • 因为着急所以没发现行、列间不会相互影响。
  • \(T3\)
    • 被题面绕晕了。
  • \(T4\)
    • 以为最终得到的差分数组的前缀和能直接转化到主席树的前缀关系上,说明对差分的本质认识不清。
    • 赛时假的思路
      • 操作 \(1\) 本质上是将现 \([l,r)\) 中的数的前缀中原 \(a_{r}\) 的出现次数加一,现 \(l\) 的前缀原 \(a_{l}\) 的出现次数少一。
      • 对每个位置开一棵权值线段树,为节省空间使用主席树代替。
      • 区间修改和区间查询的话外层套线段树维护即可。

后记

标签:线段,12,gcd,集训,T4,差分,CSP,ans,ll
From: https://www.cnblogs.com/The-Shadow-Dragon/p/18334837

相关文章

  • 暑假集训CSP提高模拟 ∫[0,6] (x^2)/6 dx
    \[\text{暑假集训CSP提高模拟}\int^{6}_{0}\frac{x^{2}}{6}dx\]A.黑客显然这个题里只有\(999\)放在复杂度里是有可能对的,要么是\(999^{2}\)要么是\(999^{2}\log999\),显然应该是前者.考虑枚举全部的最简分数,然后乘上去,算的时候直接算当前分母/分子是最简分式的几倍(注意上......
  • 暑假集训csp提高模拟12
    赛时rank47,T1100,T20,T30,T420做题策略不好,没做T2,死在T4上了。感觉赛时就是唐。T1黑客考虑枚举结果,如果存在贡献,那么一定有\(i+j=k\&gcd(i,j)=1\),统计一下有多少组即可点此查看代码#include<bits/stdc++.h>#include<bits/extc++.h>//usingnamespace__gnu_pbds;......
  • 洛谷题单指南-前缀和差分与离散化-P1083 [NOIP2012 提高组] 借教室
    原题链接:https://www.luogu.com.cn/problem/P1083题意解读:已知第i天有r[i]个教室可以供租借,有m个租借教室的订单,第i订单需要在第s[i]~t[i]天区间内租借d[i]个教室,计算是否全部订单都能满足,如果不满足要输出从第几个订单开始不满足。解题思路:1、朴素做法枚举1~m个订单,通过差分......
  • 基于ads1292的心电信号采集之芯片关键点备忘
    一前记团队在作基于ads1292的心电数据采集时候,遇到了一些问题。这里做一个记录和备忘。也希望能帮的到同样遇到困难的朋友。 二关注点1reset引脚不能悬空,这个悬空的时候,笔者发现ads1292无法正常工作。  2.start信号在单独使用的时候,不要接GND......
  • 嵌入式学习第12天——C语言循环结构
    循环结构什么是循环代码的重复执行,就叫做循环。循环的分类无限循环:程序设计中尽量避免无限循环(程序中的无限循环必须可控)。有限循环:循环限定循环次数或者循环的条件。循环的构成循环体循环条件当型循环的实现while语法: while(循环条件) { 循环语句;......
  • 21LTR.com_Scene1_2.120靶机
    getshell主机发现,端口目录扫描只有一个logs目录,接着往下扫访问首页,检查源代码,发现一组账号密码,可能是ssh,也可能是ftp的访问logs接口,没有权限尝试利用发现的账号密码,ssh没有成功,尝试ftp注意在windows上什么没有,用kali连接下载到本地查看一下拼接访问logs目录......
  • 瑞士ABB苏黎世张力控制器PFEA112-20
    其特点是控制电路结构简单、成本较低,机械特性硬度也较好,能够满足一般传动的平滑调速要求,已在产业的各个领域得到广泛应用。但是,这种控制方式在低频时,由于输出电压较低,转矩受定子电阻压降的影响比较显著,使输出大转矩减小。另外,其机械特性终究没有直流电动机硬,动态转矩能力和静态......
  • CSP模拟10--总结
    今天是我第一次给模拟赛写正规总结--因为今天的题真的受不了了四道数学题,一点都不拖泥带水的纯血数学题!T1、黑暗型高松灯shit本来是一道放在T4防AK的题,结果学长为了恶心锻炼一下我们,直接将T1和T4swap了一下.一开始看了半个小时挺懵逼的,然后跳了,但心里一直觉得这题能做......
  • 2024“钉耙编程”中国大学生算法设计超级联赛(1)1012并
    题目大意:给出n个矩形,求被k个矩形覆盖的面积的并集的期望,输出k为1-n的所一答案思路:由于是求期望所以是求出所有情况的和再除以可能的情况,每一种情况中的面积都由--同时被1个矩形覆盖,同时被两个矩形覆盖······同时被k个矩形覆盖组成,而且不难得出当k一定时,取被m个矩形覆盖的......
  • ssy中学暑假集训分数规划笔记
    分数规划出现在了我们今天的模拟赛中,看在这个名字深得我心而且我能看懂证明和内容的份上,给开个专题吧!\(1.定义\):分数规划就是求分数的极值。形象一点就是,给出\(a_i\)和\(b_i\),求一组\(w_i\in\{0,1\}\)最小化或者最大化下面的算式:\[\frac{\sum_{i=1}^{n}a_i*w_i}{\sum_{i=1}......