• Codeforces Round #775 (Div. 2) Solution Set


    暂时只有 Div. 2。

    CF1649A Game

    显然要找到最长的前缀和后缀是 \(1\),然后中间跳过去。特判全是 \(1\) 的情况,不需要花费。

    /*
    他决定要“格”院子里的竹子。于是他搬了一条凳子坐在院子里,面对着竹子硬想了七天,结果因为头痛而宣告失败。
    DONT NEVER AROUND . //
    */
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    char buf[1<<21],*p1=buf,*p2=buf;
    #define getchar() (p1==p2 && (p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
    int read()
    {
    	int x=0;
    	char c=getchar();
    	while(c<'0' || c>'9')	c=getchar();
    	while(c>='0' && c<='9')	x=(x<<1)+(x<<3)+(c^'0'),c=getchar();
    	return x;
    }
    void write(int x)
    {
    	if(x>9)	write(x/10);
    	putchar(x%10+'0');
    }
    const int MOD=998244353;
    inline int Add(int u,int v){return u+v>=MOD?u+v-MOD:u+v;}
    inline int Sub(int u,int v){return u-v>=0?u-v:u-v+MOD;}
    inline int Mul(int u,int v){return LL(u)*LL(v)%MOD;}
    int QuickPow(int x,int p)
    {
    	if(p<0)	p+=MOD-1;
    	int ans=1,base=x;
    	while(p)
    	{
    		if(p&1)	ans=Mul(ans,base);
    		base=Mul(base,base);
    		p>>=1;
    	}
    	return ans;
    }
    int a[105],n;
    void Solve()
    {
    	n=read();
    	int x=0;
    	for(int i=1;i<=n;++i)	x+=(a[i]=read());
    	if(x==n)
    	{
    		puts("0");
    		return ;
    	}
    	int sum=n+1;
    	for(int i=1;i<=n;++i)
    	{
    		if(!a[i])	break;
    		--sum;
    	}
    	for(int i=n;i;--i)
    	{
    		if(!a[i])	break;
    		--sum;
    	}
    	write(sum),puts("");
    }
    int main(){
    	int T=read();
    	while(T-->0)	Solve();
    	return 0;
    }
    

    CF1649B Game of Ball Passing

    既然官方的 Sol 也声称在猜结论,那我也猜结论吧。

    特判没传球的情况,然后考虑最大值 \(p\) 和总传球数 \(s\) 的关系。

    如果 \(2p\leq s\),答案是 \(1\);否则最大值需要踢出去 \(2p-s\) 个球,答案也是 \(2p-s\)

    /*
    他决定要“格”院子里的竹子。于是他搬了一条凳子坐在院子里,面对着竹子硬想了七天,结果因为头痛而宣告失败。
    DONT NEVER AROUND . //
    */
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    char buf[1<<21],*p1=buf,*p2=buf;
    #define getchar() (p1==p2 && (p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
    LL read()
    {
    	LL x=0;
    	char c=getchar();
    	while(c<'0' || c>'9')	c=getchar();
    	while(c>='0' && c<='9')	x=(x<<1)+(x<<3)+(c^'0'),c=getchar();
    	return x;
    }
    void write(LL x)
    {
    	if(x>9)	write(x/10);
    	putchar(x%10+'0');
    }
    LL a[100005],n;
    void Solve()
    {
    	n=read();
    	for(LL i=1;i<=n;++i)	a[i]=read();
    	for(LL i=1;i<=n;++i)	if(a[i])	goto fail;
    	puts("0");
    	return ;
    	fail:;
    	LL sum=0,maxn=0;
    	for(LL i=1;i<=n;++i)	sum+=a[i],maxn=max(maxn,a[i]);
    	if(maxn*2<=sum)	puts("1");
    	else	write(maxn-(sum-maxn)),puts("");
    }
    int main(){
    	LL T=read();
    	while(T-->0)	Solve();
    	return 0;
    }
    

    CF1648A Weird Sum

    注意到每一维独立,分开算。

    把每种颜色的某一维坐标摊开,求两两间距离。排序过后就是前缀和。

    /*
    他决定要“格”院子里的竹子。于是他搬了一条凳子坐在院子里,面对着竹子硬想了七天,结果因为头痛而宣告失败。
    DONT NEVER AROUND . //
    */
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    char buf[1<<21],*p1=buf,*p2=buf;
    #define getchar() (p1==p2 && (p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
    LL read()
    {
    	LL x=0;
    	char c=getchar();
    	while(c<'0' || c>'9')	c=getchar();
    	while(c>='0' && c<='9')	x=(x<<1)+(x<<3)+(c^'0'),c=getchar();
    	return x;
    }
    void write(LL x)
    {
    	if(x>9)	write(x/10);
    	putchar(x%10+'0');
    }
    vector<LL> C[100005][2];
    LL n,m;
    int main(){
    	n=read(),m=read();
    	for(LL i=1;i<=n;++i)	for(LL j=1;j<=m;++j)	{int c=read();C[c][0].push_back(i),C[c][1].push_back(j);}
    	for(LL i=1;i<=100000;++i)	sort(C[i][0].begin(),C[i][0].end()),sort(C[i][1].begin(),C[i][1].end());
    	LL ans=0;
    	for(LL i=1;i<=100000;++i)
    	{
    		LL sum=0,cnt=0;
    		for(auto v:C[i][0])	ans+=cnt*v-sum,++cnt,sum+=v;
    		sum=0,cnt=0;
    		for(auto v:C[i][1])	ans+=cnt*v-sum,++cnt,sum+=v;
    	}
    	write(ans);
    	return 0;
    }
    

    CF1648B Integral Array

    枚举 \(d=\left\lfloor \frac{x}{y} \right\rfloor\),将 \(a\) 去重,就可以 \(O(n \ln n)\) 暴力做了。

    /*
    他决定要“格”院子里的竹子。于是他搬了一条凳子坐在院子里,面对着竹子硬想了七天,结果因为头痛而宣告失败。
    DONT NEVER AROUND . //
    */
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    char buf[1<<21],*p1=buf,*p2=buf;
    #define getchar() (p1==p2 && (p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
    int read()
    {
    	int x=0;
    	char c=getchar();
    	while(c<'0' || c>'9')	c=getchar();
    	while(c>='0' && c<='9')	x=(x<<1)+(x<<3)+(c^'0'),c=getchar();
    	return x;
    }
    void write(int x)
    {
    	if(x>9)	write(x/10);
    	putchar(x%10+'0');
    }
    inline int lowbit(int x){return x&(-x);}
    int n,c,a[1000005];
    int sum[2000005];
    void Solve()
    {
    	n=read(),c=read();
    	for(int i=1;i<=n;++i)	a[i]=read();
    	sort(a+1,a+1+n);
    	n=unique(a+1,a+1+n)-a-1;
    	for(int i=1;i<=2*c;++i)	sum[i]=0;
    	for(int i=1;i<=n;++i)	sum[a[i]]=1;
    	for(int i=1;i<=2*c;++i)	sum[i]+=sum[i-1];
    	for(int i=1;i<=c;++i)
    	{
    		if(sum[i]==sum[i-1])
    		{
    			for(int j=1;j*i<=c;++j)
    			{
    				if(sum[j]==sum[j-1])	continue;
    				if(sum[j*(i+1)-1]^sum[i*j-1])
    				{
    					puts("No");
    					return ;
    				}
    			}
    		}
    	}
    	puts("Yes");
    }
    int main(){
    	int T=read();
    	while(T-->0)	Solve();
    	return 0;
    }
    

    CF1648C Tyler and Strings

    就纯粹傻逼 Samples & Pretests.

    枚举两个字符串相同的前缀到哪儿,然后在这个位置填一个数 \(p\) 使得 \(p < t_i\),那么后面怎么填都是合法的;然后在这里填一个 \(q=t_i\),考虑下一个位置。

    算答案的话,对于一个位置,先把所有 \(x \geq t_i\) 的填进没有填入的位置(不含当前位置)。选位置是组合数算,可重集计数要用线段树存一下值域算一下区间阶乘逆元积,用树状数组存某个值域区间里有多少数。小于 \(t_i\) 的数也是可重集计数。

    然后有巨大多 Corner Case:

    1. 如果当前的所有数都小于 \(t_i\):算完滚蛋;
    2. 如果当前填不进一个等于 \(t_i\) 的数:滚蛋;
    3. 如果 \(n<m\),并且存在一种排列方式使得 \(s = \operatorname{pre}(t,|s|)\):答案加一(记得取模)。

    就这样。傻逼题,数据还巨大多傻逼。纯粹傻逼。

    /*
    他决定要“格”院子里的竹子。于是他搬了一条凳子坐在院子里,面对着竹子硬想了七天,结果因为头痛而宣告失败。
    DONT NEVER AROUND . //
    */
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    char buf[1<<21],*p1=buf,*p2=buf;
    #define getchar() (p1==p2 && (p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
    LL read()
    {
    	LL x=0;
    	char c=getchar();
    	while(c<'0' || c>'9')	c=getchar();
    	while(c>='0' && c<='9')	x=(x<<1)+(x<<3)+(c^'0'),c=getchar();
    	return x;
    }
    void write(LL x)
    {
    	if(x>9)	write(x/10);
    	putchar(x%10+'0');
    }
    const LL MOD=998244353;
    inline LL Add(LL u,LL v){return u+v>=MOD?u+v-MOD:u+v;}
    inline LL Sub(LL u,LL v){return u-v>=0?u-v:u-v+MOD;}
    inline LL Mul(LL u,LL v){return u*v%MOD;}
    LL QuickPow(LL x,LL p=MOD-2)
    {
    	if(p<0)	p+=MOD-1;
    	LL ans=1,base=x;
    	while(p)
    	{
    		if(p&1)	ans=Mul(ans,base);
    		base=Mul(base,base);
    		p>>=1;
    	}
    	return ans;
    }
    inline LL lowbit(LL x){return x&(-x);}
    const LL UP=200000;
    struct BIT{
    	LL tr[200005];
    	void clear(){for(LL i=0;i<=UP;++i)	tr[i]=0;}
    	void modify(LL x,LL v){for(LL i=x;i<=UP;i+=lowbit(i))	tr[i]+=v;}
    	LL query(LL x){LL ret=0;for(LL i=x;i;i^=lowbit(i))	ret+=tr[i];return ret;}
    	LL query(LL l,LL r){if(l>r)	return 0;return query(r)-query(l-1);}
    }bit;
    LL fac[200005],ifac[200005];
    inline LL C(LL n,LL m){return m<0 || n<m?0:Mul(fac[n],Mul(ifac[m],ifac[n-m]));}
    LL n,m,s[200005],t[200005],app[200005];
    #define lc(x) (x<<1)
    #define rc(x) (lc(x)|1)
    #define Mm LL mid=(l+r)>>1
    LL mpl[800005];
    void push_up(LL now){mpl[now]=Mul(mpl[lc(now)],mpl[rc(now)]);}
    void build(LL l,LL r,LL now)
    {
    	if(l==r)
    	{
    		mpl[now]=ifac[app[l]];
    		return ;
    	}
    	Mm;
    	build(l,mid,lc(now)),build(mid+1,r,rc(now));
    	push_up(now);
    }
    void modify(LL l,LL r,LL now,LL x,LL v)
    {
    	if(l==r)
    	{
    		mpl[now]=ifac[v];
    		return ;
    	}
    	Mm;
    	if(x<=mid)	modify(l,mid,lc(now),x,v);
    	else	modify(mid+1,r,rc(now),x,v);
    	push_up(now);
    }
    LL query(LL l,LL r,LL now,LL x,LL y)
    {
    	if(x>y)	return 0;
    	if(x<=l && r<=y)	return mpl[now];
    	Mm,ret=1;
    	if(x<=mid)	ret=Mul(ret,query(l,mid,lc(now),x,y));
    	if(mid<y)	ret=Mul(ret,query(mid+1,r,rc(now),x,y));
    	return ret;
    }
    #undef lc
    #undef rc
    #undef Mm
    int main(){
    //	freopen("C.in","r",stdin);
    //	freopen("C.out","w",stdout);
    	fac[0]=1;
    	for(LL i=1;i<=200000;++i)	fac[i]=Mul(fac[i-1],i);
    	ifac[200000]=QuickPow(fac[200000]);
    	for(LL i=199999;~i;--i)	ifac[i]=Mul(ifac[i+1],i+1);
    	n=read(),m=read();
    	for(LL i=1;i<=n;++i)	s[i]=read();
    	for(LL i=1;i<=m;++i)	t[i]=read();
    	sort(s+1,s+1+n);
    	for(LL i=1;i<=n;++i)	bit.modify(s[i],1),++app[s[i]];
    	build(1,UP,1);
    	LL ans=0;
    	for(LL i=1;i<=min(n,m);++i)
    	{
    		LL all(bit.query(1,t[i]));
    		if(all)
    		{
    			LL st(bit.query(1,t[i]-1)),pp=bit.query(1,UP);
    			if(st==pp)
    			{
    				ans=Add(ans,Mul(fac[n-i+1],query(1,UP,1,1,UP)));
    				goto haha;
    			}
    			else
    			{
    				pp-=st;
    				ans=Add(ans,Mul(Mul(C(n-i,pp),Mul(fac[pp],query(1,UP,1,t[i],UP))),Mul(fac[st],query(1,UP,1,1,t[i]-1))));
    				if(all==st)	goto haha;
    				--app[t[i]];
    				bit.modify(t[i],-1);
    				modify(1,UP,1,t[i],app[t[i]]);
    			}
    		}
    		else	goto haha;
    	}
    	if(n<m)	ans=Add(ans,1);
    	haha:;
    	write(ans);
    	return 0;
    }
    

    CF1648D Serious Business

    定义 \(dp_i\) 为最终停在 \((2,i)\) 的最大值。那么答案就是枚举 \(i\),算 \((2,i) \to (3,i) \to (3,n)\) 的最大值。

    如何算 \(dp_i\) 呢?对于一个区间 \([l,r]\) 里的 \(i\),我们可以从 \(l-1\) 走进来,也可以从某个 \(j \in [l,i]\) 走过来。

    转移式子的话,第一种情况是:\(dp_i = dp_{l-1} + suf_{2,l} - suf_{2,i+1} - k\),第二种情况是 \(dp_i = pre_{1,j} + suf_{2,j} - suf_{2,i+1} - k\),其中 \(pre,suf\) 分别表示前缀/后缀,第一个数表示行号。可以提出共同的只跟 \(i\) 有关的 \(-suf_{2,i+1}\)

    第一种情况的话,我们将每个区间用左端点排序。这样相当于区间打 \(\max\) 的标记。求单点最大值,可以采用标记永久化。

    第二种情况,左子树会影响右子树。每个结点转移类似,可以直接打标记。

    看代码吧。

    /*
    他决定要“格”院子里的竹子。于是他搬了一条凳子坐在院子里,面对着竹子硬想了七天,结果因为头痛而宣告失败。
    DONT NEVER AROUND . //
    */
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    char buf[1<<21],*p1=buf,*p2=buf;
    #define getchar() (p1==p2 && (p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
    LL read()
    {
    	LL x=0,f=1;
    	char c=getchar();
    	while(c<'0' || c>'9')	f=(c=='-'?-1:f),c=getchar();
    	while(c>='0' && c<='9')	x=(x<<1)+(x<<3)+(c^'0'),c=getchar();
    	return x*f;
    }
    void write(LL x)
    {
    	if(x<0)	putchar('-'),x=-x;
    	if(x>9)	write(x/10);
    	putchar(x%10+'0');
    }
    LL n,q,a[4][500005],sum1[500005],sum2[500005],sum3[500005];
    #define lc(x) (x<<1)
    #define rc(x) (lc(x)|1)
    #define Mm LL mid=(l+r)>>1
    LL tr[2000005],tag[2000005],maxn[2000005];
    void build(LL l,LL r,LL now)
    {
    	tr[now]=-1e18,tag[now]=1e18;
    	if(l==r)	return void(maxn[now]=sum1[l]+sum2[l]);
    	Mm;
    	build(l,mid,lc(now)),build(mid+1,r,rc(now));
    	maxn[now]=max(maxn[lc(now)],maxn[rc(now)]);
    }
    inline void push_down(LL now){if(tag[now]!=1e18)	tr[rc(now)]=max(tr[rc(now)],maxn[lc(now)]-tag[now]),tag[lc(now)]=min(tag[lc(now)],tag[now]),tag[rc(now)]=min(tag[rc(now)],tag[now]);}
    void modify(LL l,LL r,LL now,LL x,LL y,LL v)
    {
    	if(x<=l && r<=y)
    	{
    		tr[now]=max(tr[now],v);
    		return ;
    	}
    	push_down(now);
    	Mm;
    	if(x<=mid)	modify(l,mid,lc(now),x,y,v);
    	if(mid<y)	modify(mid+1,r,rc(now),x,y,v);
    }
    void modify(LL l,LL r,LL now,LL x,LL y,LL k,LL &mxn)
    {
    	if(x<=l && r<=y)
    	{
    		tr[now]=max(tr[now],mxn-k);
    		tag[now]=min(tag[now],k);
    		mxn=max(mxn,maxn[now]);
    		return ;
    	}
    	push_down(now);
    	Mm;
    	if(x<=mid)	modify(l,mid,lc(now),x,y,k,mxn);
    	if(mid<y)	modify(mid+1,r,rc(now),x,y,k,mxn);
    }
    LL query(LL l,LL r,LL now,LL x)
    {
    	if(l==r)	return max(tr[now],maxn[now]-tag[now]);
    	push_down(now);
    	Mm,ret=tr[now];
    	if(x<=mid)	ret=max(query(l,mid,lc(now),x),ret);
    	else	ret=max(query(mid+1,r,rc(now),x),ret);
    	return ret;
    }
    #undef lc
    #undef rc
    #undef Mm
    vector<pair<LL,LL>> G[500005];
    #define mp make_pair
    LL dp[500005];
    int main(){
    	n=read(),q=read();
    	for(LL i=1;i<=3;++i)	for(LL j=1;j<=n;++j)	a[i][j]=read();
    	#define A a[1]
    	#define B a[2]
    	#define C a[3]
    	for(LL i=1;i<=n;++i)	sum1[i]=sum1[i-1]+A[i];
    	for(LL i=n;i;--i)	sum2[i]=sum2[i+1]+B[i];
    	for(LL i=n;i;--i)	sum3[i]=sum3[i+1]+C[i];
    	#undef A
    	#undef B
    	#undef C
    	build(1,n,1);
    	for(LL i=1;i<=q;++i)
    	{
    		LL l=read(),r=read(),k=read();
    		G[l].push_back(mp(r,k));
    	}
    	dp[0]=-1e18;
    	LL L=0,ans=-1e18;
    	for(LL i=1;i<=n;++i)
    	{
    		while(L<i-1)	++L,dp[L]=query(1,n,1,L)-sum2[L+1],ans=max(ans,dp[L]+sum3[L]);
    		for(auto st:G[i])
    		{
    			LL r=st.first,w=st.second;
    			modify(1,n,1,i,r,dp[i-1]+sum2[i]-w);
    			LL mxn=-1e18;
    			modify(1,n,1,i,r,w,mxn);
    		}
    	}
    	while(L<=n-1)	++L,dp[L]=query(1,n,1,L)-sum2[L+1],ans=max(ans,dp[L]+sum3[L]);
    	write(ans);
    	return 0;
    }
    
  • 相关阅读:
    php 无限极分类
    高德地图随笔
    安全随笔
    关于专线映射问题
    js小技巧总结
    php+ajax 文件上传
    去除数组中重复的元素
    关于ueditor插入不了动态地图
    vue.js 安装
    js轮播
  • 原文地址:https://www.cnblogs.com/amagaisite/p/15977001.html
Copyright © 2020-2023  润新知