首页 > 其他分享 >csp-s模拟5

csp-s模拟5

时间:2024-09-29 10:36:17浏览次数:1  
标签:cout temp int cin else maxn csp 模拟

A. 光

来自 \(K8\) 的神奇做法,根据贪心思想,一个点减四个亮度可以收益最大化,所以枚举四个灯亮度都不足4时的最终态,然后

看剩下需要亮度需要减的次数,每次选最大的那个操作就行,复杂度 \(O(16n)\)

点击查看代码
#include<bits/stdc++.h>
const int maxn=1e5+10;
using namespace std;
int A,B,C,D,ans,x,y,z,s;

int solve(int x,int y,int z,int h)
{
	int temp=0;
	while(x>0||y>0||z>0||h>0)
	{
		temp++;
		int t=max(max(x,y),max(z,h));
		if(x==t)
		{
			x-=4;y-=2;z-=2,h-=1;
		}
		else if(y==t)
		{
			y-=4;x-=2;h-=2,z-=1;
		}
		else if(z==t)
		{
			z-=4;x-=2;h-=2,y-=1;
		}
		else
		{
			h-=4;y-=2;z-=2,x-=1;
		}
	}
	return temp;
}

int main()
{
	freopen("light.in","r",stdin);
	freopen("light.out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>A>>B>>C>>D;
	int sum=A+B+C+D;
	ans=sum;
	for(int i=0;i<=3;i++)
	{
		for(int j=0;j<=3;j++)
		{
			for(int k=0;k<=3;k++)
			{
				for(int s=0;s<=3;s++)
				{
					ans=min(ans,i+j+k+s+solve(A-i-j/2-k/2,B-j-i/2-s/2,C-k-i/2-s/2,D-s-j/2-k/2)*4);
				}
			}
		}
	} 
	cout<<ans;
	
	return 0;
}
/*
400 400 400 400
*/

B. 爬

二进制拆分,计算每个点在每一位的贡献,记每个节点的直接儿子在这一位是1的个数是 \(tot\) ,则当奇数个蚂蚁爬上来时能

合成这个数,总情况 \(2^{tot-1}\) 种,不想写证明了,不会的问,还要考虑直接儿子中不是好蚂蚁的点,和其他节点的蚂蚁

他们对这个节点的这一位都没有贡献,所以他们提供了2的幂次方种方案数。还要特判根节点和只有一只蚂蚁的情况

点击查看代码
#include<bits/stdc++.h>
#define int long long
const int mod=1e9+7;
const int maxn=1e5+10;
using namespace std;
int n,a[maxn],to[maxn<<1],nxt[maxn<<1],head[maxn],tot,ans,sum[maxn]; 
int cnt[maxn][33];
void add(int x,int y)
{
	to[++tot]=y;
	nxt[tot]=head[x];
	head[x]=tot;
}
void addm(int x,int y)
{
	add(x,y);add(y,x);
}

void lsx(int x,int fa)
{
	
	for(int i=head[x];i;i=nxt[i])
	{
		int y=to[i];
		if(y==fa) continue;
		lsx(y,x);
		for(int j=0;j<=30;j++)
		{
			if(a[y]&(1<<j)) cnt[x][j]++;
			sum[x]+=cnt[x][j];
		}
	}
	if(x==1) return ;
	for(int i=0;i<=30;i++)
	{
		if(a[x]&(1<<i)) cnt[x][i]++;
	}
}

int qpow(int x,int y)
{
	if(y<0) return 0;
	int temp=1;
	while(y)
	{
		if(y&1)temp=1ll*temp*x%mod;
		x=1ll*x*x%mod;
		y>>=1;
	}
	return temp;
}

void solve(int x,int fa)
{
	int tot=(x!=1);
	for(int i=head[x];i;i=nxt[i])
	{
		int y=to[i];
		if(y==fa) continue;
		tot++;
		solve(y,x);	
	}
	int temp=0;
	for(int i=0;i<=30;i++)
	{
		if(x==1)
		{
			if(a[x]&(1<<i))
			{
				if(!cnt[x][i]) temp=(temp+1ll*(1<<i)*(qpow(2,tot)-1)%mod)%mod;
				else temp=(temp+1ll*(1<<i)*(qpow(2,cnt[x][i]-1)*qpow(2,tot-cnt[x][i])%mod-1+mod)%mod)%mod; 
			}
			else
			{
				if(!cnt[x][i])continue;
				temp=(temp+1ll*(1<<i)*qpow(2,cnt[x][i]-1)%mod*qpow(2,tot-cnt[x][i])%mod)%mod;
			}
		}
		else
		{
			if(!cnt[x][i])continue;
			temp=(temp+1ll*(1<<i)*(qpow(2,cnt[x][i]-1)*qpow(2,tot-cnt[x][i])%mod-cnt[x][i]+mod)%mod)%mod;
		}
	}
	ans=(ans+1ll*temp*qpow(2,n-1-tot)%mod)%mod;
}

signed main()
{
	freopen("climb.in","r",stdin);
	freopen("climb.out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=2;i<=n;i++)
	{
		int x;
		cin>>x;
		addm(x,i);
	}
	lsx(1,0);
	solve(1,0);
	cout<<ans;

	return 0;
}
/*
3
1 2 4
1 2
*/

C. 字符串

粘个题解吧,挺详细的

image

点击查看代码
#include<bits/stdc++.h>
const int maxn=110;
using namespace std;
int t,N,M,A,B,C;

int main()
{
	freopen("string.in","r",stdin);	
//	freopen("1.out","w",stdout);
	freopen("string.out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>t;
	while(t--)
	{
		int ans=0;
		cin>>N>>M>>A>>B>>C;
		for(int i=1,temp=0;i<=min(N,M/C);i++)
		{
			temp=0;
			int n=N,m=M,a=A,b=B,c=C;
			n-=i,m-=c*i;
			temp+=2*i;
			if(n)n--,temp++;
			temp+=n/a;
			if(m)m--,temp++;
//			cout<<temp<<endl;
			if(b<c) temp+=i*floor((c-1)/b);
//			cout<<i<<" "<<temp<<endl;
			if(m)
			{
				if(b>=c)
				{
					int s=(b+1-c);
//					cout<<m<<endl;
					if(s*i>=m) temp+=m/s;
					else temp+=i+(m-i*s)/b;	
				}
				else
				{
					int s=(c-1)%b;
					int k=b-s;
					if(k*i>=m) temp+=m/k;
					else temp+=i+(m-i*k)/b;	
				}	
			}
//			cout<<temp<<" "<<i<<endl;
			ans=max(ans,temp);
		}
		if(!(M/C))
		{
			ans=2+(N-1)/A+(M-1)/B;
		}
		cout<<ans<<'\n';
	}

	return 0;
}
/*
1
10 10 6 2 4
*/

D. 奇怪的函数

分块,维护每一个块的分段函数的转折点,查询直接每个块判一下与转折点的位置就知道答案,修改就直接推平重构

点击查看代码
#include<bits/stdc++.h>
#define int long long
const int maxn=1e5+10;
using namespace std;
int n,q,sum[maxn],shu,len,l[501],r[501],blo[maxn],up[501],down[501],f[501];
struct lsx
{
	int opt,val;
}a[maxn];

void build()
{
	for(int i=1;i<=shu;i++)
	{
		l[i]=(i-1)*len+1;
		r[i]=i*len;
	}
	if(r[shu]<n)shu++,l[shu]=r[shu-1]+1,r[shu]=n;
	for(int i=1;i<=shu;i++)
	{
		for(int j=l[i];j<=r[i];j++)blo[j]=i,up[i]=1e15,down[i]=-1e15;
		for(int j=l[i];j<=r[i];j++)
		{
			if(a[j].opt==1) up[i]+=a[j].val,down[i]+=a[j].val,f[i]+=a[j].val;
			if(a[j].opt==2) up[i]=min(up[i],a[j].val),down[i]=min(down[i],a[j].val);
			if(a[j].opt==3) up[i]=max(up[i],a[j].val),down[i]=max(down[i],a[j].val);
		} 
	}
}

void solve(int x)
{
	up[x]=1e15,down[x]=-1e15,f[x]=0; 
	for(int i=l[x];i<=r[x];i++)
	{
		if(a[i].opt==1) up[x]+=a[i].val,down[x]+=a[i].val,f[x]+=a[i].val;
		if(a[i].opt==2) up[x]=min(up[x],a[i].val),down[x]=min(down[x],a[i].val);
		if(a[i].opt==3) up[x]=max(up[x],a[i].val),down[x]=max(down[x],a[i].val);
	}
}

void lsx(int x)
{
	for(int i=1;i<=shu;i++)
	{
		if(x+f[i]>=up[i]) x=up[i];
		else if(x+f[i]<=down[i]) x=down[i];
		else x=x+f[i];
	}
	cout<<x<<'\n';
}

signed main()
{
	freopen("function.in","r",stdin);
	freopen("function.out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		int x,y;
		cin>>x>>y;
		a[i]={x,y};
	}
	shu=(int)pow(n*1.0,1.0/2*1.0);
    len=(int)(n*1.0/shu*1.0);
    build();
	cin>>q;
	for(int i=1;i<=q;i++)
	{
		int op,x,y;
		cin>>op>>x;
		if(op==4)
		{
			lsx(x);
			continue;
		}
		cin>>y;
		a[x]={op,y};
		solve(blo[x]);
	}

	return 0;
}
/*
10
1 48
1 50
1 180
2 957
1 103
1 100
1 123
3 500
1 66
1 70
3
4 20
4 50
4 700
*/

标签:cout,temp,int,cin,else,maxn,csp,模拟
From: https://www.cnblogs.com/oceansofstars/p/18439088

相关文章

  • [赛记] csp-s模拟5
    光100pts赛时打的错解A了,就很神奇;其实可以发现答案有可二分性,考虑二分答案,每次check时枚举左上角和右下角的耗电量,然后对左下角的耗电量再进行二分,最后判定以下即可;赛时就这么打的,然后赛后拍出来了;其实这个思路是对的,只是$\lfloor\fracn4\rfloor$这个条件有误差,所以暴......
  • csp模拟赛 6 9.28
    0+40+10+0一言以蔽之曰“一上午白干”T1一般图最小匹配首先,对答案有贡献的点对一定在排序后的位于相邻位置所以排序后取出所有\(a_{i+1}-a_{i}\)但不能像Kruskal一样每次取最小,因为其只需要考虑连通性,不涉及其它限制。所以用dp或者可反悔贪心取最优解点击查看代码#in......
  • 『模拟赛』csp-s模拟赛6
    『模拟赛』csp-s模拟赛6挂分日寄:0+20+0+0喵喵赛时对拍拍了10000个点都没拍出来,赛后一下就拍出错来了,我谔谔。T1DP喵~首先sort一遍方便处理其实转移时加一个abs取绝对值就可,纯纯多此一举设\(f[i,j,1/0]\)为前\(i\)个数中选\(j\)个的最小值若选当前这个数,则\(f[i......
  • 2024.9.28 代码源模拟赛
    省流:\(45+20+5+0=70\)简称:唐诗在此膜拜\(klz\)\(Heldivis\)\(Sorato\)\(czl\)\(Ech0\_7\)yxanslihe_qwq大佬T1先看的T1,想了一个拓排(其实是看错题了),然后过了第一个样例,然后咋调都过不去,就去码暴力了。过了大概10min发现看错题了,然后一会就想出来个\(O(n^2)\)......
  • 代码源 2024 CSP-S 模拟赛 Day 6
    赛时开T1,发现立即有了\(O(n^2)\)的思路,能有\(45\)分,但是先不急,看看后面的题。T2、T3、T4似乎都可以写个暴力。又想了想,T1还需要求出个LCA,所以复杂度是\(O(n^2\logn)\)的,开写。很快写完,调不过,边界很不好处理。直到\(1.5\)h才调出来\(O(n^2\logn)\)。上个厕所......
  • CSP-S 2024 第六次
    A排序之后只会选相邻的,直接DP。B从前往后考虑每个数\(a_i\)要不要删。若不删\(a_i\):若\(a_i\ne0\),则\(a_i\)已经确定。若\(a_i=0\),则\(a_i\)可取所有没出现过的数,以及\(i\)后最小的数(先删掉它再把\(a_i\)赋成它)若删掉\(a_i\):若\(a_{i+1}\ne0\),则\(a......
  • 『模拟赛』CSP-S模拟6
    Rank一般恼了怎么又狠狠挂分啊啊啊啊A.一般图最小匹配签。(这么多天终于签上了是吧)结论是,跟图完全没关系。题意转换完就是从\(n\)个数中选出\(m\)对差的绝对值之和最小的数。显然我们选的每一对数都应该是这\(n\)个数中相邻的一组,sort一下,设\(f_{i,j,k}\)表示到......
  • CSP-S 2022~2023 补题
    下面的代码都是远古代码,不打算重写了。CSP-S2023T1密码锁题意:一个密码锁上有\(5\)个位置,每个位置上的数字是\(0\sim9\)的循环,每次打乱会选择一或两个相邻位置同时循环移动。给定\(n\)个打乱后的状态,求有多少种可能的原状态。\(n\le8\)。容易发现可能的状态数......
  • [DMY]2024 CSP-S 模拟赛 Day 6
    前言离A掉一道题最近的一次。过程看完T1以后,想先构一个\(\mathcal{O}(n^3)\)的暴力,但是发现只有10pts,而且算法复杂度接近\(\mathcal{O}(n^4)\),所以果断放弃。把链的限制写了(然后亏大了),然后开始在CS上面画画。画了一会发现一个简单的dp思路,但是是\(\mathcal{O}(n^......
  • CSP & NOIP 模拟赛记录
    9.18(lanos212)T1签到,10mins内过了。T2乍一看有点困难,题目太形式化,不太直观,先跳过去思考T3了,T3没有什么DP的思路,但是这种题显然需要DP。看了一眼T4,被一堆式子糊脸恶心了,没有怎么思考。接下来一个小时在思考T2和T3,突然发现T2只需要每次求最短路就可以了,那么就是......