首页 > 其他分享 >AtCoder Regular Contest 102

AtCoder Regular Contest 102

时间:2023-09-27 19:13:35浏览次数:29  
标签:AtCoder main int namespace Regular ans 102 include 逆序

C - Triangular Relationship

枚举 \(a\bmod k\) 的值,\(b\bmod k,c\bmod k\) 的值也就确定了,算下贡献就好了。

#include<iostream>
#include<cstdio>
using namespace std;
int n,k;
int main()
{
	scanf("%d%d",&n,&k);
	long long ans=0;
	for(int a=0;a<k;a++)
	{
		int b=(-a+k)%k;
		int c=(-a+k)%k;
		if((b+c)%k!=0) continue;
		int ca=n/k+(a<=n%k),cb=n/k+(b<=n%k),cc=n/k+(c<=n%k);
		if(a==0) ca--;
		if(b==0) cb--;
		if(c==0) cc--;
		ans+=1LL*ca*cb*cc;
	}
	printf("%lld",ans);
	return 0;
}

D - All Your Paths are Different Lengths

\(n\le 20\) 容易让人想到二进制拆分。发现可以构造出 \([0,2^{n-1})\) 的方案来,具体的说,我们在 \((i,i+1)\) 中连权值为 \(0,2^{i-1}\) 的两条边。然后考虑 \(L\) 怎么做,将 \(L\) 的每一位分离开来,如果 \(L\) 的第 \(i-1\) 位为 \(0\),在 \((i,n)\)中连一条权值为将后 \(i\) 位置为 \(0\) 后的 \(L\) 的权值。


#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
#include<tuple>
using namespace std;
int L;
int n,m;
vector<tuple<int,int,int>>edge;
int main()
{
	scanf("%d",&L);
	int n=log2(L)+1;
	for(int i=1;i<n;i++)
		edge.emplace_back(i,i+1,1<<(i-1)),edge.emplace_back(i,i+1,0);
	for(int i=1;i<n;i++)
		if(L&(1<<(i-1))) edge.emplace_back(i,n,(L>>i)<<i);
	int m=edge.size();
	printf("%d %d\n",n,m);
	for(auto [u,v,w]:edge)
		printf("%d %d %d\n",u,v,w);
	return 0;
}

E - Stop. Otherwise...

对于每次询问,我们可以将数分成两个部分,一部分是选了当前这个数不能选另一个数,另一部分是选了当前这个数对于其他数没有影响。令 \(f_{i,j}\) 表示考虑前一部分的 \(i\) 种颜色填满 \(j\) 个位置的方案数,\(g_{i,j}\) 表示后一部分的 \(i\) 种颜色(每种颜色如果存在可以换成另一种)填满 \(j\) 个位置的方案数。直接转移是 \(O(n^2m)\) 的,前缀和优化一波就是 \(O(nm)\) 的。每次询问暴力合并一下就好了。


#include<iostream>
#include<cstdio>
using namespace std;
const int N=2005;
const int MOD=998244353;
int n,m;
int f[N][N],g[N][N];
int sumf[N][N],sumg[N][N];
int pw2[N];
int main()
{
	scanf("%d%d",&m,&n);
	sumf[0][0]=f[0][0]=1;
	for(int j=1;j<=n;j++)
		sumf[0][j]=(sumf[0][j-1]+f[0][j])%MOD;
	for(int i=1;i<=m;i++)
	{
		for(int j=0;j<=n;j++)
			f[i][j]=f[i-1][j];
		for(int j=1;j<=n;j++)
			f[i][j]=(f[i][j]+sumf[i-1][j-1])%MOD;
		sumf[i][0]=f[i][0];
		for(int j=1;j<=n;j++)
			sumf[i][j]=(sumf[i][j-1]+f[i][j])%MOD;
	}
	sumg[0][0]=g[0][0]=1;
	for(int j=1;j<=n;j++)
		sumg[0][j]=(sumg[0][j-1]+g[0][j])%MOD;
	for(int i=1;i<=m;i++)
	{
		for(int j=0;j<=n;j++)
			g[i][j]=g[i-1][j];
		for(int j=1;j<=n;j++)
			g[i][j]=(g[i][j]+2LL*sumg[i-1][j-1])%MOD;
		sumg[i][0]=g[i][0];
		for(int j=1;j<=n;j++)
			sumg[i][j]=(sumg[i][j-1]+g[i][j])%MOD;
	}
	for(int i=2;i<=2*m;i++)
		if(i%2==0)
		{
			int cnt1=i>m?i-m-1:m-i+1,cnt2=i>m?m-i/2:(i-1)/2;
			int ans=0;
			ans=(ans+f[cnt1][n])%MOD;
			for(int j=1;j<=n;j++)
				ans=(ans+1LL*g[cnt2][j]%MOD*f[cnt1][n-j])%MOD;
			ans=(ans+1LL*f[cnt1][n-1])%MOD;
			for(int j=1;j<=n-1;j++)
				ans=(ans+1LL*g[cnt2][j]%MOD*f[cnt1][n-1-j])%MOD;
			printf("%d\n",ans);
		}
		else
		{
			int cnt1=i>m?i-m-1:m-i+1,cnt2=i>m?m-i/2:i/2;
			int ans=0;
			ans=(ans+f[cnt1][n])%MOD;
			for(int j=1;j<=n;j++)
				ans=(ans+1LL*g[cnt2][j]%MOD*f[cnt1][n-j])%MOD;
			printf("%d\n",ans);
		}
	return 0;
}

Revenge of BBuBBBlesort!

一次操作相当于交换两个距离为 \(1\) 的数,所以如果奇数位置上有偶数,偶数位置上奇数显然是不合法的。

把奇数位和偶数位分成两个排列,一次操作会使得原排列中的逆序对减少 \(3\),分割后的排列的逆序对减少 \(1\)。

所以可以发现一个必要条件即为原序列的逆序对个数为 \(3\) 的倍数,且为奇数位和偶数位的 \(3\) 倍。

可以证明这也是充分条件。

  1. 如果交换后原序列的逆序对数减少了 \(3\),那么这一定是一个合法的操作。
  2. 考虑对分开后的两个排列冒泡排序,每次这两个排列中的某一个逆序对数会减少 \(3\)。

则可以发现每次操作都是满足第一个条件的,所以只要满足第二个条件就是合法的。


#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=300005;
int n;
int p[N];
struct BIT
{
	int C[N];
	void clear()
	{
		memset(C,0,sizeof(C));
		return;
	}
	int lowbit(int x)
	{
		return x&-x;
	}
	void add(int x,int y)
	{
		for(int i=x;i<=n;i+=lowbit(i))
			C[i]+=y;
		return;
	}
	int getsum(int x)
	{
		int res=0;
		for(int i=x;i>0;i-=lowbit(i))
			res+=C[i];
		return res;
	}
	int query(int l,int r)
	{
		return getsum(r)-getsum(l-1);
	}
}T;
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&p[i]);
	for(int i=1;i<=n;i++)
		if(p[i]%2!=i%2)
		{
			printf("No");
			return 0;
		}
	long long cnt=0;
	for(int i=1;i<=n;i++)
		cnt+=T.query(p[i]+1,n),T.add(p[i],1);
	T.clear();
	long long cnt1=0;
	for(int i=1;i<=n;i+=2)
		cnt1+=T.query(p[i]+1,n),T.add(p[i],1);
	T.clear();
	long long cnt2=0;
	for(int i=2;i<=n;i+=2)
		cnt2+=T.query(p[i]+1,n),T.add(p[i],1);
	if(cnt%3==0&&3*(cnt1+cnt2)==cnt) printf("Yes");
	else printf("No");
	return 0;
}

标签:AtCoder,main,int,namespace,Regular,ans,102,include,逆序
From: https://www.cnblogs.com/zhou-jk/p/17733606.html

相关文章

  • AtCoder Regular Contest 103
    C-////如果奇数和偶数出现的颜色的最大值相同一边取最大值和一边取次大值,否则两边都选最大值即可。#include<iostream>#include<cstdio>#include<algorithm>usingnamespacestd;constintN=100005;intn,m;intv[N];intc[N];intmain(){ scanf("%d",&n); for(in......
  • AtCoder Grand Contest 048
    A-atcoder<S枚举操作完的串\(s\)和atcoder相同的前缀长度,算出前面的前缀相同的代价加上当前这位大于atcoder中对应的那一位的代价即为达到当前状态的代价,取个最小值即可。#include<iostream>#include<cstdio>#include<cstring>usingnamespacestd;constintN=1......
  • AtCoder Grand Contest 046
    A-Takahashikun,TheStrider问题就是要你求\(ax\equiv0\pmod{360}\)中\(a\)的最小值。答案就是\(a=\frac{360}{\gcd(x,360)}\)。代码:#include<iostream>#include<cstdio>usingnamespacestd;intx;intgcd(inta,intb){ returnb==0?a:gcd(b,a%b);......
  • AtCoder Grand Contest 047
    A-IntegerProduct考虑将原来的数全部化为整数,乘上\(10^9\),那么问题就变成了是否有两个数的乘积是\(10^{18}\)的倍数。考虑如果是\(10^{18}\)的倍数的话必然是\(2^{18}\)和\(5^{18}\)的倍数,那么分解出每个数的\(2,5\)因子数量,然后再看看有多少个数与它\(2,5\)的因......
  • AtCoder Grand Contest 043
    A-RangeFlipFindRoute可以发现,一条路径的最小操作数等于路径上有多少#的块,令\(f_{i,j}\)表示到\((i,j)\)的最小操作次数,直接DP就行了。注意路径上一个\(1\)的块会被算两次,需要除以\(2\)。#include<iostream>#include<cstdio>#include<cstring>usingnamesp......
  • AtCoder Grand Contest 044
    A-PaytoWin不妨将操作倒过来考虑,问题就变成了每次除以\(2,3,5\)或者\(+1,-1\),令\(f_n\)表示将\(n\)变成\(0\)的最小花费,然后记忆化搜索即可,可以证明复杂度是对的。代码:#include<iostream>#include<cstdio>#include<map>usingnamespacestd;intT;longlong......
  • AtCoder Grand Contest 045
    A-XorBattle可以发现,从后往前扫,遇到一个\(1\)找后面是否有若干个\(0\)的位置的\(a_i\)与当前位置的异或和相等,用线性基维护一下就好了。代码:#include<iostream>#include<cstdio>#include<cstring>usingnamespacestd;constintN=205;intT;intn;longlong......
  • SR10200肖特基整流二极管 杭州东沃 原厂厂家
    近日,前来东沃电子咨询肖特基二极管的客户特别地多起来了:SS315LB肖特基二极管,有生产的吗?DO-27封装肖特基二极管,贵司有哪些型号?反向电压200V的直插肖特基二极管,有哪些常用型号?SR10200二极管200V10ADO-27封装,需要200K,什么价格?交期多久?……肖特基二极管有直插和贴片之分,直插封装形式......
  • nginx访问报错“maximum number of descriptors supported by select() is 1024 while
    1、问题背景 项目:一个人力的系统,主要用于考勤打卡环境:windowsservernginx版本:1.22 问题说明:当早上访问人数增加的时候,就会出现nginx的异常nginx的后台报错日志:maximumnumberofdescriptorssupportedbyselect()is1024whileconnectingtoupstream  ......
  • AtCoder Beginner Contest 318
    AtCoderBeginnerContest318A-FullMoon(atcoder.jp)以\(M\)为首项,\(P\)为公差,看\(1\simN\)里包含了多少项的个数#include<bits/stdc++.h>usingi64=longlong;usingnamespacestd;typedefpair<i64,i64>PII;intmain(){ios::sync_with_stdio......