ABC T5 树形dp求调
  • 板块学术版
  • 楼主xzy_AK_IOI
  • 当前回复4
  • 已保存回复4
  • 发布时间2025/2/1 21:48
  • 上次更新2025/2/2 12:45:19
查看原帖
ABC T5 树形dp求调
1183074
xzy_AK_IOI楼主2025/2/1 21:48
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define F(i,k,n) for (int i=k;i<=n;i++)
typedef long long ll;
const int N=3e6;
struct node{
	int left,mid,right;
	string data;
	char l;
	string ans;
	int sum0[5];
}tree[N];
int fa[N];
int dp[N];
int n,tot=1;
string s;
int p[10];
bool ans;
int _pow(int a,int b){
	int ans=1;F(i,1,b) ans*=a;return ans;
}
void build(string s,int now,int j){
	if (now==1) return ;
	tot++;
	fa[tot]=fa[tot+1]=fa[tot+2]=j;
	tree[j].left=tot;
	tree[j].mid=tot+1;
	tree[j].right=tot+2;
	tree[tot].data=s.substr(0,now/3);
	tree[tot+1].data=s.substr(now/3,now/3);
	tree[tot+2].data=s.substr(2*(now/3),now/3);
	tot+=2;int p=tot;
	build(tree[p-2].data,now/3,p-2);
	build(tree[p-1].data,now/3,p-1);
	build(tree[p].data,now/3,p);
}
char init(int now){
	if ((int)tree[now].data.size()==1) {return tree[now].l;}
	memset(tree[now].sum0,0,sizeof tree[now].sum0);
	tree[now].sum0[init(tree[now].left)-'0']++;
	tree[now].sum0[init(tree[now].mid)-'0']++;
	tree[now].sum0[init(tree[now].right)-'0']++;
	tree[now].l=(tree[now].sum0[1]>tree[now].sum0[0]?'1':'0');
	return tree[now].l;
}
int dfs(int now){
	//cout<<now<<'\n';
	if (dp[now]==1 || dp[now]==0) return dp[now];
	if (tree[now].sum0[ans]<tree[now].sum0[(!ans)]){
		int u=tree[now].sum0[ans];
		u=2-u;
		if (u==2){
			p[1]=dfs(tree[now].left);
			p[2]=dfs(tree[now].mid);
			p[3]=dfs(tree[now].right);
			sort(p+1,p+1+3);
			dp[now]=p[1]+p[2];
		}
		else{
			int minn=1e9;
			if (tree[tree[now].left].l-'0'!=ans) minn=min(minn,dfs(tree[now].left));
			if (tree[tree[now].mid].l-'0'!=ans) minn=min(minn,dfs(tree[now].mid));
			if (tree[tree[now].right].l-'0'!=ans) minn=min(minn,dfs(tree[now].right));
			dp[now]=minn;
		}
		return dp[now];
	}
	else return dp[now]=0;
}
signed main(){
	cin>>n>>s;
	memset(dp,0x3f,sizeof dp);
	tree[1].data=s;
	build(s,_pow(3,n),1);
	F(i,1,tot) if ((int)tree[i].data.size()==1) tree[i].l=tree[i].data[0];
	ans=(init(1)-'0');
	ans=(!ans);cout<<ans;
	F(i,1,tot) if ((int)tree[i].data.size()==1){
		if ((tree[i].data[0]-'0')==ans) dp[i]=0;
		else dp[i]=1;
	}
	
	cout<<dfs(1);
	F(i,1,tot) //cout<<dp[i]<<' '<<tree[i].data<<'\n';
	return 0;
}

2025/2/1 21:48
加载中...