ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

ACSX: Aug, 2022

2022-08-02 19:04:31  阅读:215  来源: 互联网

标签:ch ACSX Aug int register read while 2022 getchar


8.1

T2数据水,只判4条边界就可以85pts,随机化2e5个非整点判断可以AC。
T2:

正解是扫描线,但是没人写。

T1 wisdom


我们采用一种贪心,假设当前已经处理完 u 的所有儿子子树,考虑把 u 染成什么颜色最优

// ubsan: undefined
// accoders
#include <bits/stdc++.h>
#define pii pair<int,int>
#define fi first
#define se second
using namespace std;
inline int read(){
	register char ch=getchar();register int x=0;
	while(ch<'0'||ch>'9')ch=getchar();
	while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
	return x;
}
const int N=2e6+5;
int n,a[N];
vector<int>f[N],G[N];
int dfs(int x){
	if(a[x]){f[x].emplace_back(a[x]);return 1;}
	int ret=0,mx=0;
    unordered_map<int,int>mp;
    for(int y:G[x]){
        ret+=dfs(y);
        for(int i:f[y]){
        	if(++mp[i]>mx)mx=mp[i],f[x].clear(),f[x].shrink_to_fit(),f[x].emplace_back(i);
        	else if(mp[i]==mx)f[x].emplace_back(i);
        }
		f[y].clear(),f[y].shrink_to_fit();
    }
	return ret-mx+1;
}
int main(){
	freopen("wisdom.in","r",stdin);freopen("wisdom.out","w",stdout);
	n=read();
	for(int i=2,fa;i<=n;i++)fa=read(),G[fa].emplace_back(i);
	for(int i=1;i<=n;i++)a[i]=read();
	cout<<dfs(1);
}

8.2

T1 reward


“恰好”二字清晰提示了 wqs 二分,照常注意细节。

// ubsan: undefined
// accoders
#include <bits/stdc++.h>
#define int long long
using namespace std;
inline int read(){
	register char ch=getchar();register int x=0;
	while(ch<'0'||ch>'9')ch=getchar();
	while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
	return x;
}
typedef long long ll;
const int N=2e6+5;
int n,m,k,a[N],b[N],f[N],g[N],sum,ans;
int calc(int mid){
	for(int i=1;i<=n;i++)b[i]=a[i]+mid;
	f[0]=g[0]=0;
	for(int i=1;i<=n;i++){
		if(f[max(i-m,0ll)]+b[i]>=f[i-1])f[i]=f[max(i-m,0ll)]+b[i],g[i]=g[max(i-m,0ll)]+1;//>=
		else f[i]=f[i-1],g[i]=g[i-1];
	}
	return g[n];
}
signed main(){
	freopen("reward.in","r",stdin);freopen("reward.out","w",stdout);
	n=read(),m=read(),k=read();
	for(int i=1;i<=n;i++)a[i]=read();
	int L=-2e9,R=2e9,mid;
	while(L<R-1){
		mid=(L+R)/2;
		int t=calc(mid);
		if(t>=k)R=mid;
		else L=mid;
	}
	int t=calc(R);
	cout<<f[n]-R*k<<'\n';
}

T2 冬之花



容易想到这是可以平面图转对偶图跑最短路的。但是我有两点问题:①没有把对偶图形态画出来观察②没学过ddp
把对偶图形态画出来就会发现:
那么左边的两个线头可以看成一个起始点,显然可以 dp:
\(f[i][0]=min(f[i-1][0]+a[i],f[i-1][1]+c[i-1]+a[i])\)
\(f[i][1]=min(f[i-1][1]+b[i],f[i-1][0]+c[i-1]+b[i])\)
有经验的选手很容易看到“修改边权”就联想到动态 dp,再一看 [0][1] 就是板子题了。

|o[i-1][0] o[i-1][1]|×|a[i]         c[i-1]+b[i]|
                      |c[i-1]+a[i]         b[i]|

线段树维护区间积即可。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//o[i][0]=min(o[i-1][0]+a[i],o[i-1][1]+c[i-1]+a[i])
//o[i][1]=min(o[i-1][1]+b[i],o[i-1][0]+c[i-1]+b[i])
//|o[i-1][0] o[i-1][1]|*|a[i]         c[i-1]+b[i]|
//                      |c[i-1]+a[i]         b[i]|
inline int read(){
	register char ch=getchar();register int x=0;
	while(ch<'0'||ch>'9')ch=getchar();
	while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
	return x;
}
void print(ll x){
	if(x/10)print(x/10);
	putchar(x%10+48);
}
const int N=5e5+5;
struct Mat1 {ll o[2];Mat1(){o[0]=o[1]=0;}}tmp;
struct Mat2 {ll o[2][2];Mat2(){o[0][0]=o[0][1]=o[1][0]=o[1][1]=0;}}t[N<<2];
int n,q,a[N],b[N],c[N];
Mat1 operator*(Mat1 a,Mat2 b){
	Mat1 c;
	c.o[0]=min(a.o[0]+b.o[0][0],a.o[1]+b.o[1][0]);
	c.o[1]=min(a.o[0]+b.o[0][1],a.o[1]+b.o[1][1]);
	return c;
}
Mat2 operator*(Mat2 a,Mat2 b){
	Mat2 c;
	c.o[0][0]=min(a.o[0][0]+b.o[0][0],a.o[0][1]+b.o[1][0]);
	c.o[0][1]=min(a.o[0][0]+b.o[0][1],a.o[0][1]+b.o[1][1]);
	c.o[1][0]=min(a.o[1][0]+b.o[0][0],a.o[1][1]+b.o[1][0]);
	c.o[1][1]=min(a.o[1][0]+b.o[0][1],a.o[1][1]+b.o[1][1]);
	return c;
}
void pushup(int k){t[k]=t[k<<1]*t[k<<1|1];}
void build(int l,int r,int k){
	if(l==r){
		t[k].o[0][0]=a[l],t[k].o[0][1]=c[l]+b[l],t[k].o[1][0]=c[l]+a[l];t[k].o[1][1]=b[l];
		return;
	}
	int mid=l+r>>1;
	build(l,mid,k<<1),build(mid+1,r,k<<1|1);
	pushup(k);
}
void chg(int type,int p,int l,int r,int k){
	if(l==r){
		if(type==1)t[k].o[0][0]=a[p],t[k].o[1][0]=c[p]+a[p];
		if(type==2)t[k].o[0][1]=c[p]+b[p],t[k].o[1][1]=b[p];
		if(type==3)t[k].o[0][1]=c[p]+b[p],t[k].o[1][0]=c[p]+a[p];
		return;
	}
	int mid=l+r>>1;
	if(p<=mid)chg(type,p,l,mid,k<<1);
	else chg(type,p,mid+1,r,k<<1|1);
	pushup(k);
}
Mat2 ask(int L,int R,int l,int r,int k){
	if(L<=l&&r<=R)return t[k];
	int mid=l+r>>1;
	if(L<=mid&&R>mid)return ask(L,R,l,mid,k<<1)*ask(L,R,mid+1,r,k<<1|1);
	if(L<=mid)return ask(L,R,l,mid,k<<1);
	return ask(L,R,mid+1,r,k<<1|1);
}
int main(){
	freopen("hana.in","r",stdin);freopen("hana.out","w",stdout);
	n=read(),q=read();
	for(int i=1;i<=n;i++)a[i]=read();
	for(int i=1;i<=n;i++)b[i]=read();
	for(int i=2;i<=n;i++)c[i]=read();
	build(1,n,1);
	for(int op,l,r;q--;){
		op=read(),l=read(),r=read();
		if(op==1)a[l]=r,chg(1,l,1,n,1);
		if(op==2)b[l]=r,chg(2,l,1,n,1);
		if(op==3)c[l+1]=r,chg(3,l+1,1,n,1);
		if(op==4){
			tmp.o[0]=tmp.o[1]=0,tmp=tmp*ask(l,r,1,n,1),print(min(tmp.o[0],tmp.o[1])),puts("");
		}
	}
}

标签:ch,ACSX,Aug,int,register,read,while,2022,getchar
来源: https://www.cnblogs.com/impyl/p/16544824.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有