首页 > 其他分享 >AtCoder Beginner Contest 355

AtCoder Beginner Contest 355

时间:2024-10-07 22:01:03浏览次数:1  
标签:AtCoder return Beginner int 355 ans include iut getchar

ABC355 A - Who Ate the Cake?

题目传送门


代码(签到题)

#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
using namespace std;
int iut(){
    int ans=0,f=1; char c=getchar();
    while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
    while (isdigit(c)) ans=ans*10+c-48,c=getchar();
    return ans*f;
}
int main(){
    int n=iut(),m=iut();
    if (n==m) printf("-1");
        else printf("%d",6-n-m);
    return 0;
}

ABC355 B - Piano 2

题目传送门


代码(签到题)

#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
using namespace std;
int n,m,a[211],b[211];
int iut(){
    int ans=0,f=1; char c=getchar();
    while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
    while (isdigit(c)) ans=ans*10+c-48,c=getchar();
    return ans*f;
}
int main(){
    n=iut(),m=iut();
    for (int i=1;i<=n;++i) a[i]=iut();
    for (int i=1;i<=m;++i) b[i]=iut();
    sort(a+1,a+1+n),sort(b+1,b+1+m);
    int I=1,J=1,flag=0;
    while (I<=n&&J<=m)
    if (a[I]<b[J]){
        if (flag) return !printf("Yes");
        flag=1,++I;
    }else ++J,flag=0;
    if (I<n) return !printf("Yes");
        else printf("No");
    return 0;
}

ABC355 C - Bingo 2

题目传送门


代码(签到题)

#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=2011;
int n,T,row[N],column[N],zhu,fu;
int iut(){
    int ans=0,f=1; char c=getchar();
    while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
    while (isdigit(c)) ans=ans*10+c-48,c=getchar();
    return ans*f;
}
int main(){
    n=iut(),T=iut();
    for (int i=1;i<=T;++i){
        int t=iut(),x=(t-1)/n+1,y=t-(x-1)*n;
        ++row[x],++column[y];
        if (x==y) ++zhu;
        if (x+y==n+1) ++fu;
        if (row[x]==n||column[y]==n||zhu==n||fu==n)
            return !printf("%d",i);
    }
    return !printf("-1");
}

ABC355 D - Intersecting Intervals

题目传送门


分析

考虑容斥,用总数减去不相交的区间数,不相交的区间数可以用树状数组实现


代码

#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=1000011;
long long ans;
int n,m,l[N],r[N],b[N],c[2][N];
int iut(){
    int ans=0,f=1; char c=getchar();
    while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
    while (isdigit(c)) ans=ans*10+c-48,c=getchar();
    return ans*f;
}
void update(int x,int z){
    for (;x<=m;x+=-x&x) ++c[z][x];
}
int query(int x,int z){
    int ans=0;
    for (;x;x-=-x&x) ans+=c[z][x];
    return ans;
}
int main(){
    n=iut();
    for (int i=1;i<=n;++i){
        l[i]=iut(),r[i]=iut();
        b[++m]=l[i],b[++m]=r[i];
    }
    sort(b+1,b+1+m),m=unique(b+1,b+1+m)-b-1;
    ans=n*(n-1ll)/2;
    for (int i=1;i<=n;++i){
        l[i]=lower_bound(b+1,b+1+m,l[i])-b;
        r[i]=lower_bound(b+1,b+1+m,r[i])-b;
        ans-=query(l[i]-1,0)+i-1-query(r[i],1);
        update(r[i],0),update(l[i],1);
    }
    return !printf("%lld",ans);
}

ABC355 E - Guess the Sum

题目传送门


分析

实际上,连续和的求值可以变成两个前缀和相减的形式,而 \((L,R)\) 区间最多只有 \(n2^n\) 个,

要求询问次数最少,询问实际上只与端点有关,询问次数实际上是最短路,那么使用 BFS 找到最短路的路径,利用路径完成交互。


代码

#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
const int N=300011; queue<int>q;
int pre[N],lg[N],n,L,R,ans,z;
void doit(int x){
    if (pre[x]==pre[L]) return;
    if (pre[x]<x) cout<<"? "<<lg[x-pre[x]]<<' '<<pre[x]/(x-pre[x])<<endl,cin>>z,ans=(ans+z)%100;
        else cout<<"? "<<lg[pre[x]-x]<<' '<<x/(pre[x]-x)<<endl,cin>>z,ans=(ans+100-z)%100;
    doit(pre[x]);
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    cin>>n>>L>>R,++R,lg[0]=pre[0]=-1;
    for (int i=1;i<=(1<<n);++i) pre[i]=-1,lg[i]=lg[i>>1]+1;
    pre[L]=(1<<n)+1,q.push(L);
    while (!q.empty()){
        int x=q.front(); q.pop();
        if (x==R){
            doit(R);
            cout<<"! "<<ans<<endl;
            return 0;
        }
        if (!x){
            for (int z=1;z<pre[L];z<<=1)
                if (pre[z]==-1) q.push(z),pre[z]=x;
            continue;
        }
        for (int z=-x&x;z;z>>=1){
            if (x+z<pre[L]&&pre[x+z]==-1) q.push(x+z),pre[x+z]=x;
            if (pre[x-z]==-1) q.push(x-z),pre[x-z]=x;
        }
    }
    return 0;
}

ABC355 F - MST Query

题目传送门


分析

边权最多 \(10\) 种,一开始是一棵树,那么一开始的答案就是所有边权之和,

那么开 \(10\) 个并查集,第 \(i\) 个并查集中只装入边权大于等于 \(i\) 的边,

对于每个询问,将边丢入相应的并查集内,如果该边构成了新的生成树,说明原边被替换了,

假设原边的边权为 \(x\),新边的边权为 \(y\),那么在第 \(y\sim x-1\) 个并查集中均添加了新边,

减去 \(x-y\) 的贡献,所以就是添加一个新边,就将答案减一。


代码

#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=200011;
int n,Q,f[10][N],ans;
int iut(){
    int ans=0; char c=getchar();
    while (!isdigit(c)) c=getchar();
    while (isdigit(c)) ans=ans*10+c-48,c=getchar();
    return ans;
}
void print(int ans){
    if (ans>9) print(ans/10);
    putchar(ans%10+48);
}
int getf(int j,int u){return f[j][u]==u?u:f[j][u]=getf(j,f[j][u]);}
int main(){
    n=iut(),Q=iut();
    for (int j=1;j<10;++j)
        for (int i=1;i<=n;++i) f[j][i]=i;
    for (int i=1;i<n;++i){
        int x=iut(),y=iut(),z=iut();
        ans+=z;
        for (int j=z;j<10;++j)
            f[j][getf(j,x)]=f[j][getf(j,y)];
    }
    for (int i=1;i<=Q;++i){
        int x=iut(),y=iut(),z=iut();
        for (int j=z;j<10;++j)
        if (getf(j,x)!=getf(j,y))
            f[j][getf(j,x)]=f[j][getf(j,y)],--ans;
        else break;
        print(ans),putchar(10);
    }
    return 0;
}

ABC355 G - Baseball

题目传送门


分析

乘上了 \(\sum_{i=1}^nP_i\),不妨令第 \(0\) 个位置和第 \(n+1\) 个位置必选但在最小值时不可用。

那么题目就转换成了恰好选择 \(k\) 个点分成 \(k+1\) 段,对于相邻的选择点 \(x,y\),使得 \(\sum\sum_{i=x+1}^{y-1}\min\{i-x,y-i\}\times P_i\) 最小

设 \(dp[i][j]\) 表示前 \(i\) 个位置分成了 \(j\) 段的最小值,第二维由于式子满足四边形不等式,可利用决策单调性进行优化。

即使优化后仍是于事无补,考虑利用 WQS 二分斜率强加贡献,那么就变成了 \(O(n\log n\log k)\),貌似斜率的二分上界要上到 long long


代码

#include <cstdio>
#include <cctype>
#include <algorithm>
using namespace std;
const int N=50011; int n,m,head,tail,K[N],a[N],f[N],q[N];
typedef long long lll; lll dp[N],s[N],S[N],ans;
int iut(){
	int ans=0; char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
	return ans;
}
lll calc(int l,int r){
	if (l>r) return 0;
	if (l==1&&r==n) return 1e12;
	if (l==1) return (s[r]-s[l-1])*(r+1)-(S[r]-S[l-1]);
	if (r==n) return (S[r]-S[l-1])-(s[r]-s[l-1])*(l-1);
	int mid=(l+r)>>1;
	return (S[mid]-S[l-1])-(s[mid]-s[l-1])*(l-1)+(s[r]-s[mid])*(r+1)-(S[r]-S[mid]);
}
int ef(int X,int Y){
	int l=Y+1,r=n+2;
	while (l<r){
	    int mid=(l+r)>>1;
		if (dp[X]+calc(X+1,mid-1)>=dp[Y]+calc(Y+1,mid-1)) r=mid;
		    else l=mid+1;
	}
	return l;
}
void doit(lll mid){
	head=tail=0;
	for (int i=1;i<=n+1;++i){
		while (head<tail&&K[head]<=i) ++head;
		dp[i]=dp[q[head]]+calc(q[head]+1,i-1)+mid,f[i]=f[q[head]]+1;
		while (head<tail&&K[tail-1]>=ef(q[tail],i)) --tail;
		K[tail]=ef(q[tail],i),q[++tail]=i;
	}
}
int main(){
	n=iut(); m=iut()+1;
	for (int i=1;i<=n;++i) a[i]=iut();
	for (int i=1;i<=n;++i) s[i]=s[i-1]+a[i],S[i]=S[i-1]+1ll*a[i]*i;
	lll l=0,r=623623623617ll;
	while (l<r){
		lll mid=(l+r+1)>>1; doit(mid);
		if (f[n+1]>=m) ans=dp[n+1]-m*mid,l=mid;
		    else r=mid-1;
	}
	return !printf("%lld",ans);
}

标签:AtCoder,return,Beginner,int,355,ans,include,iut,getchar
From: https://www.cnblogs.com/Spare-No-Effort/p/18450750

相关文章

  • AtCoder Beginner Contest 373
    ABC373A-September题目传送门代码(签到题)#include<cstdio>#include<cstring>usingnamespacestd;chars[1111];intans;intmain(){for(inti=1;i<=12;++i){scanf("%s",s+1);if(strlen(s+1)==i)++ans;}pr......
  • Solution - Atcoder ARC116C Multiple Sequences
    一个\(\mathcal{O}(m^{\frac{3}{4}}\logm)\)做法。令\(a_0=1\)。对于倍数问题,考虑类似差分的思想,定义\(b_i=\frac{a_i}{a_{i-1}}(1\lei\len)\),那么合法的\(a\)和\(b\)是双射的,就只需要考虑对\(b\)计数了。考虑到因为有\(\prod\limits_{i=1}^nb_i\lem\)......
  • AtCoder Beginner Contest 374
    ABC374A-Takahashisan2题目传送门代码(签到题)#include<cstdio>#include<cctype>#include<cstring>#include<cmath>#include<queue>usingnamespacestd;intiut(){ intans=0,f=1;charc=getchar(); while(!isdigit(c))f=(c==&......
  • AtCoder Beginner Contest 374
    省流版A.判断末三位即可B.逐位判断即可C.枚举所有分组情况即可D.枚举线段顺序、端点顺序即可E.二分答案,发现贵的机器数量不超过\(100\),枚举求最小花费看是否可行即可F.朴素DP,复杂度分析得到有效时刻不超过\(O(n^2)\)而非\(O(s_i)\),直接\(DP\)即可A-Takahashi......
  • AtCoder Beginner Contest 373
    省流版A.暴力即可B.求出字母位置,绝对值相加即可C.显然答案为两个数组的最大值的和D.注意直接BFS的点权范围不超过题目范围,直接BFS即可E.发现单调性,二分票数,用前缀和\(O(1)\)判断可行性即可F.朴素背包DP,相同重量的物品一起考虑,用优先队列求解\(l\)个相同重量物品最大......
  • Solution - Atcoder ARC157E XXYX Binary Tree
    考虑这个不存在\(\texttt{YY}\)的限制,与\(\texttt{XX}\)个数为变量的限制相比较,看起来\(\texttt{Y}\)就更特殊,于是考虑从\(\texttt{Y}\)的视角来分析问题。同时考虑到因为有\(A+B+C=n-1\),所以\(\texttt{XX}\)其实也不是很重要,因为只需要让\(\texttt{XY}\)和......
  • Solution - Atcoder ARC157D YY Garden
    考虑到因为有横轴数轴两部分的限制,不妨先固定下来一部分的限制再处理另一部分。对于这题来说横轴竖轴本质是相同的,于是不妨考虑固定横轴。如果知道了横轴的分割,那么对于竖轴上就可以根据分割情况知道合法的分割了。即考虑记\(f_i\)为考虑了竖轴的前\(i\)列,第\(i\)列为最......
  • AtCoder Beginner Contest 365
    A-LeapYear思路模拟即可;AC代码#include<bits/stdc++.h>#defineendl'\n'#defineintintlonglong#definepbpush_back#definebsbitsetusingnamespacestd;typedefpair<char,int>PCI;typedefpair<......
  • 题解:AtCoder Beginner Contest AT_abc373_d ABC373D Hidden Weights(格式美化版)
    题目传送门题目翻译给你一个NNN个点,MMM条边的有向图,其中边有边......
  • AtCoder Beginner Contest 365题解
    A-LeapYear按照题意模拟即可。codeB-SecondBest按照题意模拟即可。codeC-TransportationExpenses考虑当\(x\)增大时,\(\min(x,a_i)=x\)的项会越来越少。换言之,当\(x\)足够大时,\(ans=\suma_i\),若此时\(ans>M\)则说明无论补贴多少,这时答案都是一定的......