首页 > 其他分享 >Dwango Programming Contest V

Dwango Programming Contest V

时间:2023-09-27 19:26:47浏览次数:37  
标签:x1 Contest int res Programming long y1 include Dwango

A - Thumbnail

直接按照题意模拟。。。


#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
const int N=105;
int n;
int a[N];
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	int sum=0;
	for(int i=1;i<=n;i++)
		sum+=a[i];
	double avg=(double)sum/n;
	double Min=1e9;
	int t=0;
	for(int i=1;i<=n;i++)
		if(abs(a[i]-avg)<Min) Min=abs(a[i]-avg),t=i;
	printf("%d",t-1);
	return 0;
}

B - Sum AND Subarrays

把 \(\frac{n(n-1)}{2}\) 个区间和分别找出来,按位确定即可,如果当前位可以为 \(1\) 将所有的当前位为 \(0\) 删除。


#include<iostream>
#include<cstdio>
#include<bitset>
using namespace std;
const int N=1005;
int n;
long long k;
int a[N];
long long sum[N];
long long v[N*N];
int tot;
bool check(long long x)
{
	int cnt=0;
	for(int i=1;i<=tot;i++)
		if((v[i]&x)==x) cnt++;
	return cnt>=k;
}
int main()
{
	scanf("%d%lld",&n,&k);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	for(int i=1;i<=n;i++)
		sum[i]=sum[i-1]+a[i];
	for(int l=1;l<=n;l++)
		for(int r=l;r<=n;r++)
			v[++tot]=sum[r]-sum[l-1];
	long long res=0;
	for(int i=60;i>=0;i--)
		if(check(res|(1LL<<i))) res|=1LL<<i;
	printf("%lld",res);
	return 0;
}

C - k-DMC

从前往后维护一个类似单调队列的东西,队列里维护合法的 D 的位置。

如果遇到一个 M,我们需要将当前队列里所有的 D 加上 \(1\);遇到一个 D 我们将它加入队列;遇到一个 C 计算一次所有队列里合法的数贡献之和。


#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
const int N=1000005;
int n,Q;
char s[N];
void solve()
{
	int k;
	scanf("%d",&k);
	deque<pair<int,int>>q;
	int add=0;
	long long sum=0;
	long long ans=0;
	for(int i=1;i<=n;i++)
	{
		while(!q.empty()&&i-q.front().first>=k) sum-=q.front().second,q.pop_front();
		if(s[i]=='D')
		{
			q.emplace_back(i,-add);
			sum+=-add;
		}
		else if(s[i]=='M') add++;
		else if(s[i]=='C') ans+=1LL*add*q.size()+sum;
	}
	printf("%lld\n",ans);
	return;
}
int main()
{
	scanf("%d",&n);
	scanf("%s",s+1);
	scanf("%d",&Q);
	while(Q--)
		solve();
	return 0;
}

D - Square Rotation

对于 \((x,y)\),它和 \((x\bmod D,y\bmod D)\) 是等价的,我们可以讨论对于模 \(D\) 剩余系的所有点的情况,下文的 \(A_{x,y}\) 表示模 \(D\) 剩余系下 \((x,y)\) 的点的个数。

最终答案可以表示成 \(aD+b\) 的形式,不妨令矩形左下角为 \((0,0)\),\(cnt_{i,j}\) 表示模 \(D\) 剩余系下 \((i,j)\) 在矩形中有几个,则:

  • 对于 \(0\leq i,j\leq b\) 的情况,\(cnt_{i,j}=(a+1)^2\);
  • 对于 \(b< i,j< D\) 的情况,\(cnt_{i,j}=a^2\);
  • 对于剩下的情况,\(cnt_{i,j}=a(a+1)\)。

需要满足的条件为 \(A_{i,j}\leq cnt_{i,j}\),我们需要找到一个最小的 \(a\),使得 \((a+1)^2\ge \max\{A_{i,j}\}\),\(a\) 的最小值为 \(\sqrt{\max\{A_{i,j}\}}-1\),考虑计算 \(b\)。

显然可以二分 \(b\),可以枚举矩形的左下角,判断合法。

对于 \(a^2< A_{i,j}\leq a(a+1)\),判断一下 \(A_{i,j}\) 有没有在 \(a^2\) 的地方出现。

对于 \(a(a+1)< A_{i,j} \leq (a+1)^2\) 的数,判断一下 \(A_{i,j}\) 是否都在 \((a+1)^2\) 的地方。


#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
const int N=100005,M=2005;
int n,D;
int x[N],y[N];
int cnt[M][M];
int s2[M][M],s3[M][M];
int getsum2(int x1,int y1,int x2,int y2)
{
	if(x1>x2) return 0;
	if(y1>y2) return 0;
	int res=s2[x2][y2];
	if(x1-1>=0) res-=s2[x1-1][y2];
	if(y1-1>=0) res-=s2[x2][y1-1];
	if(x1-1>=0&&y1-1>=0) res+=s2[x1-1][y1-1];
	return res;
}
int getsum3(int x1,int y1,int x2,int y2)
{
	if(x1>x2) return 0;
	if(y1>y2) return 0;
	int res=s3[x2][y2];
	if(x1-1>=0) res-=s3[x1-1][y2];
	if(y1-1>=0) res-=s3[x2][y1-1];
	if(x1-1>=0&&y1-1>=0) res+=s3[x1-1][y1-1];
	return res;
}
bool check2(int x,int y,int b)
{
	return getsum2(x+b+1,y+b+1,x+D-1,y+D-1)==0;
}
bool check3(int x,int y,int b)
{
	return getsum3(x,y,x+b,y+b)==getsum3(0,0,D-1,D-1);
}
int main()
{
	scanf("%d%d",&n,&D);
	for(int i=1;i<=n;i++)
		scanf("%d%d",&x[i],&y[i]);
	for(int i=1;i<=n;i++)
		cnt[x[i]%D][y[i]%D]++;
	int a=0;
	for(int i=0;i<D;i++)
		for(int j=0;j<D;j++)
			a=max(a,(int)ceil(sqrt(cnt[i][j])));
	a--;
	for(int i=0;i<D;i++)
		for(int j=0;j<D;j++)
		{
			if(cnt[i][j]>a*a&&cnt[i][j]<=a*(a+1)) s2[i][j]++;
			else if(cnt[i][j]>a*(a+1)) s3[i][j]++;
		}
	for(int i=0;i<D;i++)
		for(int j=0;j<D;j++)
			s2[i+D][j]=s2[i][j+D]=s2[i+D][j+D]=s2[i][j],s3[i+D][j]=s3[i][j+D]=s3[i+D][j+D]=s3[i][j];
	for(int i=0;i<D+D;i++)
		for(int j=0;j<D+D;j++)
		{
			if(i-1>=0) s2[i][j]+=s2[i-1][j];
			if(j-1>=0) s2[i][j]+=s2[i][j-1];
			if(i-1>=0&&j-1>=0) s2[i][j]-=s2[i-1][j-1];
			if(i-1>=0) s3[i][j]+=s3[i-1][j];
			if(j-1>=0) s3[i][j]+=s3[i][j-1];
			if(i-1>=0&&j-1>=0) s3[i][j]-=s3[i-1][j-1];
		}
	int res=D-1;
	for(int i=0;i<D;i++)
		for(int j=0;j<D;j++)
		{
			int l=0,r=D-1,ans=-1;
			while(l<=r)
			{
				int mid=(l+r)/2;
				if(check2(i,j,mid)&&check3(i,j,mid)) ans=mid,r=mid-1;
				else l=mid+1;
			}
			if(ans!=-1) res=min(res,ans);
		}
	printf("%d",a*D+res);
	return 0;
}

E - Cyclic GCDs

首先有一个 DP,令 \(f_{i,j}\) 表示前 \(i\) 个数组成了 \(j\) 个环的总和。转移为:

\[f_{i,j}=a_if_{i-1,j-1}+(i-1)f_{i-1,j} \]

答案为 \(\gcd(f_{n,i})\)。

考虑 \(f_i\) 的生成函数 \(P(n)\),则 \(P(n)=P(n-1)(a_ix+(i-1))\),其中 \(P(0)=1\)。可以推出:

\[P(n)=\prod\limits_{i=1}^n (a_ix+(i-1)) \]

然后就有一个结论:

令 \(w(P)\) 表示 \(P\) 的各项系数的 \(\gcd\),则 \(w(PQ)=w(P)\cdot w(Q)\)。

首先 \(w(P)\cdot w(Q)|w(PQ)\),我们需要证明的即为当 \(w(P)=w(Q)=1\) 时,\(w(PQ)=1\)。

考虑反证,设 \(P,Q\) 分别有 \(n,m\) 项。如果 \(w(PQ)\) 有一个质因子 \(p\),则 \(PQ\) 的最高次项为 \(P_nQ_mx^{n+m}\),则 \(P_n,Q_m\) 必然有一个是 \(p\) 的倍数,我们可以将这个位置的数删去,然后继续考虑剩下的位置。这样做下去,必然有一个多项式 \(P\) 或 \(Q\) 被删到了空,则这个多项式系数会有一个公因数 \(p\),矛盾,故假设不成立。

所以答案即为 \(\prod\limits_{i=1}^n\gcd(a_i,i-1)\)。


#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=100005;
const int MOD=998244353;
int n;
int a[N];
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	sort(a+1,a+n+1);
	long long ans=1;
	for(int i=1;i<=n;i++)
		ans=ans*__gcd(a[i],i-1)%MOD;
	printf("%lld",ans);
	return 0;
}

标签:x1,Contest,int,res,Programming,long,y1,include,Dwango
From: https://www.cnblogs.com/zhou-jk/p/17733870.html

相关文章

  • M-SOLUTIONS Programming Contest
    A-SumofInteriorAngles答案为\(180(n-2)\)。#include<iostream>#include<cstdio>usingnamespacestd;intn;intmain(){ scanf("%d",&n); printf("%d",180*(n-2)); return0;}B-Sumo判断一下x的个数是否小于等于\(7\)。#......
  • Keyence Programming Contest 2020
    A-Painting每次取\(H,W\)中较大者涂就是了,输出\(\lceil\frac{n}{\max(H,W)}\rceil\)。代码:#include<iostream>#include<cstdio>usingnamespacestd;inth,w,n;intmain(){ scanf("%d%d%d",&h,&w,&n); if(h<w)swap(h,w); ......
  • NOMURA Programming Competition 2020
    A-StudyScheduling先算出总时间,然后在减去\(K\)就好了。代码:#include<iostream>#include<cstdio>usingnamespacestd;inth1,m1,h2,m2,k;intmain(){ scanf("%d%d%d%d%d",&h1,&m1,&h2,&m2,&k); intansh=h2-h1,ansm=m2-m1; if......
  • NIKKEI Programming Contest 2019-2
    A-SumofTwoIntegers分奇偶讨论一下就好了,答案为\(\lfloor\frac{n-1}\{2\}\rfloor\)。#include<iostream>#include<cstdio>usingnamespacestd;intn;intmain(){ scanf("%d",&n); printf("%d",(n-1)/2); return0;}B-......
  • Tenka1 Programmer Contest 2019
    C-Stones枚举分界点爆算即可。#include<iostream>#include<cstdio>usingnamespacestd;constintN=200005;intn;chars[N];intsum[N][2];intmain(){ scanf("%d",&n); scanf("%s",s+1); sum[0][0]=sum[0][1]=0; for(inti=1;i......
  • Social Infrastructure Information Systems Division, Hitachi Programming Contest
    A-HitachiString满足条件的串即为串长为偶数且相邻两个均为为hi,直接判断即可。代码:#include<iostream>#include<cstdio>#include<cstring>usingnamespacestd;constintN=15;intn;chars[N];intmain(){ scanf("%s",s+1); n=strlen(s+1); if(n&1) ......
  • Yahoo Programming Contest 2019
    A-Anti-Adjacency合法的条件即为\(k\leq\lceil\frac{n}{2}\rceil\)。#include<iostream>#include<cstdio>usingnamespacestd;intn,k;intmain(){ scanf("%d%d",&n,&k); if((n+1)/2>=k)printf("YES"); elsepri......
  • Tokio Marine & Nichido Fire Insurance Programming Contest 2020
    A-Nickname直接输出前三个字符。代码:#include<iostream>#include<cstdio>usingnamespacestd;constintN=25;chars[N];intmain(){ scanf("%s",s+1); printf("%c%c%c",s[1],s[2],s[3]); return0;}B-Tag如果\(v\leqw\),则显然不......
  • AtCoder Grand Contest 025
    A-DigitsSum按题意模拟即可。#include<iostream>#include<cstdio>usingnamespacestd;constintINF=1061109567;intn;intcalc(intx){intres=0;while(x)res+=x%10,x/=10;returnres;}intmain(){scanf("%d",&......
  • AtCoder Grand Contest 026
    A-ColorfulSlimes2可以发现,对于连续的一段长度为\(m\)的相同的字符,我们可以花费\(\lfloor\frac{m}{2}\rfloor\)的代价将它改为符合要求的。#include<iostream>#include<cstdio>usingnamespacestd;constintN=105;intn;inta[N];intmain(){scanf("%d"......