• 【AtCoder】AtCoder Grand Contest 040 解题报告


    点此进入比赛

    (A):><(点此看题面

    大致题意: 给你一个长度为(n-1)、由(<)(>)组成的的字符串,第(i)位的字符表示第(i)个数和第(i+1)个数的大小关系,求这个由非负整数组成的数组中元素和的最小值。

    送分题都想了几分钟才做出来,真是退役预警......

    显然,对于所有小于两旁的数,我们给它赋值为(0),然后再从它们向两边扩展即可。

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 500000
    #define Gmax(x,y) (x<(y)&&(x=(y)))
    using namespace std;
    int n,H=1,T=0,a[N+5],q[N+5],vis[N+5];string s;
    int main()
    {
    	RI i,k;cin>>s,n=s.length()+1,s="%"+s+"%",s[1]=='<'&&(q[++T]=1),s[n-1]=='>'&&(q[++T]=n);
    	for(i=2;i^n;++i) s[i-1]=='>'&&s[i]=='<'&&(q[++T]=i);W(H<=T) k=q[H++],
    		s[k-1]=='>'&&(Gmax(a[k-1],a[k]+1),!vis[k-1]&&(vis[q[++T]=k-1]=1)),//向左扩展
    		s[k]=='<'&&(Gmax(a[k+1],a[k]+1),!vis[k+1]&&(vis[q[++T]=k+1]=1));//向右扩展
    	long long ans=0;for(i=1;i<=n;++i) ans+=a[i];return printf("%lld",ans),0;//统计答案
    }
    

    (B):Two Contests(点此看题面

    大致题意:(n)个区间,让你把它划分成非空的两部分,使得两部分区间交集大小之和最大。

    首先,我们要知道,对于一些区间([l_i,r_i]),它们的交集大小是(max(min{r_i}-max{l_i}+1,0))

    因此,可以先将区间按左端点排序,然后枚举其中一个区间左端点最大值为(l_i),则另一个区间左端点最大值为(l_n)

    而对于右端点,有两种可能性。

    设第(1sim i)条线段中最小的(r)(r_{min}),最大的为(r_{max}),第(i+1sim n)中最小的(r)(Mn)

    那么最优情况下,两个集合的(min{r_i})要么分别是(r_{min},Mn),要么分别是(r_{max},min(r_{min},Mn))

    确定了左端点和右端点,我们就可以因此而更新答案了。

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 100000
    #define max(x,y) ((x)>(y)?(x):(y))
    #define min(x,y) ((x)<(y)?(x):(y))
    #define Gmax(x,y) (x<(y)&&(x=(y)))
    using namespace std;
    int n;set<int> p,q;
    struct Il {int x,y;I bool operator < (Con Il& o) Con {return x<o.x;}}s[N+5];
    class FastIO
    {
    	private:
    		#define FS 100000
    		#define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
    		#define tn (x<<3)+(x<<1)
    		#define D isdigit(c=tc())
    		char c,*A,*B,FI[FS];
    	public:
    		I FastIO() {A=B=FI;}
    		Tp I void read(Ty& x) {x=0;W(!D);W(x=tn+(c&15),D);}
    }F;
    int main()
    {
    	RI i,j,t,ans=0;for(F.read(n),i=1;i<=n;++i) F.read(s[i].x),F.read(s[i].y);
    	for(sort(s+1,s+n+1),i=1;i<=n;++i) q.insert(s[i].y);//排序,一开始默认所有线段在第二个集合
    	for(i=1;i<=n;++i) q.erase(s[i].y),p.insert(s[i].y),t=0,//枚举一个区间的左端点最大值,把对应右端点移入第一个集合中
    		Gmax(t,max(*--p.end()-s[i].x+1,0)+max(min(*p.begin(),*q.begin())-s[n].x+1,0)),//第一种情况
    		Gmax(t,max(*p.begin()-s[i].x+1,0)+max(*q.begin()-s[n].x+1,0)),Gmax(ans,t);//第二种情况,更新ans
    	return printf("%d",ans),0;
    }
    
    

    (C):Neither AB nor BA(点此看题面

    大致题意: 对于一个由(A,B,C)三种字符组成的字符串,每次可以删除连续两个不为ABBA的字符,求有多少个长度为(n)的字符串可以删空。

    首先,我们考虑不存在(C)的情况。

    此时,若我们把奇数位上的(A)变成(B)(B)(A),就可以发现,当且仅当(A)(B)的个数相同时,这个字符串可以删空。

    同时由于改变后的字符串与原字符串一一对应,所以只要求出改变后的字符串的个数,就可以求出答案。

    再考虑存在(C),由于(C)可以视为(A)(B)中的任意一种,因此只要满足(A)(B)的个数之差个数小于等于(C)的个数,就可以删空。

    考虑这个答案可以容斥,即求出(A)(B)的个数之差大于(C)的个数的方案数,然后用总方案数将其减去。

    则此时必然存在(A)(B)中的某一种有(i)个((i>frac n2)),而剩余(n-i)个位置可以任意填另一种字母和(C)

    即此时的方案数为:

    [C_n^i imes 2^{n-i} ]

    因此预处理阶乘及阶乘逆元,(O(n))枚举(i),统计答案即可。

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 10000000
    #define X 998244353
    #define C(x,y) (1LL*Fac[x]*IFac[y]%X*IFac[(x)-(y)]%X)
    using namespace std;
    int n,Fac[N+5],IFac[N+5];
    I int Qpow(RI x,RI y) {RI t=1;W(y) y&1&&(t=1LL*t*x%X),x=1LL*x*x%X,y>>=1;return t;}//快速幂
    int main()
    {
    	RI i,t=0;for(scanf("%d",&n),Fac[0]=i=1;i<=n;++i) Fac[i]=1LL*Fac[i-1]*i%X;//预处理阶乘
    	for(IFac[n]=Qpow(Fac[n],X-2),i=n-1;~i;--i) IFac[i]=1LL*IFac[i+1]*(i+1)%X;//预处理阶乘逆元
    	for(i=n/2+1;i<=n;++i) t=(1LL*C(n,i)*Qpow(2,n-i)+t)%X;//计算答案
    	return printf("%d",(Qpow(3,n)-2*t%X+X)%X),0;//容斥,注意乘2
    }
    

    (D):Balance Beam(占坑待填)

    (E):Prefix Suffix Addition(占坑待填)

    (F):Two Pieces(占坑待填)

  • 相关阅读:
    Spring Boot SOAP系列之WSDL是什么“Lese”
    MyBatis源码分析和纯手写MyBatis框架集合
    哪吒:我命由我不由天
    手写MyBatis,纯手工打造开源框架(第四篇:决胜千里)- 第272篇
    Linux Submitting Patch
    Setting Up MySQL Debugging Environment
    How to mannuly configure vmtools in VM-Ware?
    How to mannuly configure vmtools in VM-Ware?
    Install 32bit libraries in 64 bit ubuntu(14.10)
    The easiest way to extract/uncompress files
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/AtCoderAGC040.html
Copyright © 2020-2023  润新知