The 1st Universal Cup Stage 12: ̄Ookayama, April 15-16, 2023 题解

A XOR Tree Path

给一颗树,树上点有黑白两色,每次可以选一个叶子节点,翻转其到根路径上所有点的颜色,问最大黑色点数。
树dp

#include<bits/stdc++.h> 
using namespace std;
#define MAXN (100000+10)
#define ll long long
#define F (100000000)
#define Rep(i,n) for(int i=0;i<n;i++)
#define next Next
int n,edge[MAXN*2],pre[MAXN],next[MAXN*2],Size=0;
int f[MAXN][2];
int a[MAXN];
int g[2];
void addedge(int u,int v)
{
	edge[++Size]=v;
	next[Size]=pre[u];
	pre[u]=Size;
}
void dfs(int x,int father)
{
	bool lef=1;
	int g[2];
	for (int p=pre[x];p;p=next[p])
	{
		int &v=edge[p];
		if (v!=father)
		{
			dfs(v,x);
			if(lef) {
				f[x][0]=g[0]=f[v][0];
				f[x][1]=g[1]=f[v][1];
				lef=0;
			}
			else {
				f[x][0]=max(g[0]+f[v][0],g[1]+f[v][1]);
				f[x][1]=max(g[1]+f[v][0],g[0]+f[v][1]);
				g[0]=f[x][0],g[1]=f[x][1];
			}
		}
	}	
	
	if(lef) f[x][0]=a[x],f[x][1]=a[x]^1;
	else f[x][0]+=a[x],f[x][1]+=a[x]^1;
}
int main()
{
//	freopen("a.in","r",stdin);
	scanf("%d",&n);
	memset(pre,0,sizeof(pre));
	memset(next,0,sizeof(next));
	for(int i=1;i<=n;i++) cin>>a[i];
	for (int i=1;i<n;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		addedge(u,v);addedge(v,u);
	}
	dfs(1,0);	
	cout<<max(f[1][0],f[1][1]);
	return 0;
}

B Magical Wallet

You have a magical wallet with X yen in it. (Yen is the currency of Japan.)
Using the magic on this wallet, you can rearrange the amount of money in the wallet as a decimal string
in any order you like. For example, if you have a magical wallet with 120 yen, you can use magic to change
the amount of money in the wallet to any of the following: 12 yen, 21 yen, 102 yen, 120 yen, 201 yen, or
210 yen (leading zeros are ignored).
You will now visit N shops with the magical wallet in order. At the i-th shop (1 ≤ i ≤ N ), a product
costing Ai yen is sold, and if the magical wallet contains at least Ai yen, you can pay Ai yen from the
magical wallet to buy the product.
You can use magic as much as you like whenever you want. How many products can you buy at most?

直接暴力模拟过程

#include<bits/stdc++.h> 
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
						For(j,m-1) cout<<a[i][j]<<' ';\
						cout<<a[i][m]<<endl; \
						} 
#pragma comment(linker, "/STACK:102400000,102400000")
#define ALL(x) (x).begin(),(x).end()
#define gmax(a,b) a=max(a,b);
#define gmin(a,b) a=min(a,b);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
inline int read()
{
	int x=0,f=1; char ch=getchar();
	while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
	while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
	return x*f;
} 
vi get(int x) {
	stringstream ss;
	ss<<x;
	char s[6];
	ss>>s;
	int m=strlen(s);
	vi v;
	sort(s,s+m);
	do{
		stringstream ss;
		ss<<s;
		int p;ss>>p;
		v.pb(p);
//		cout<<p<<" ";
	}while(next_permutation(s,s+m));
	return v;
}
#define MAXX (10000+10)
int f[101][MAXX];
vi v[MAXX];
int main()
{
//	freopen("B.in","r",stdin);
//	freopen(".out","w",stdout);
	int n,x;
	Rep(i,1e4) {
		v[i]=get(i);
	}
//	Rep(i,20) {
//		for(int j:v[i]) cout<<j<<' ';cout<<endl;
//	}
	cin>>n>>x;
	get(x);
	MEMi(f)
	for(int i:v[x])f[0][i]=0;
	Rep(i,n) {
		int cx=read();
		Rep(j,10000)gmax(f[i+1][j],f[i][j])
		Rep(j,10000) {
			if(f[i][j]>=0 && j>=cx) {
				for(int k:v[j-cx])
					gmax(f[i+1][k],f[i][j]+1)
			}
		}
	} 
	int t=0;
	Rep(j,10000) gmax(t,f[n][j])
	cout<<t<<endl;	
	return 0;
}

E Five Med Sum

在这里插入图片描述
枚举中位数,注意可以事先给A-E数组定个顺序,以防算重。

#include<bits/stdc++.h> 
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (998244353)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
						For(j,m-1) cout<<a[i][j]<<' ';\
						cout<<a[i][m]<<endl; \
						} 
#pragma comment(linker, "/STACK:102400000,102400000")
#define ALL(x) (x).begin(),(x).end()
#define gmax(a,b) a=max(a,b);
#define gmin(a,b) a=min(a,b);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
inline int read()
{
	int x=0,f=1; char ch=getchar();
	while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
	while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
	return x*f;
} 
//class node{
//	int x,t;
//	bool friend operator<(node a,node b) {
//		if(a.x<b.x)
//	}
//};
vector<pair<int,int > > v[5];
int main()
{
//	freopen("E.in","r",stdin);
//	freopen(".out","w",stdout);
	int n=read();
	Rep(j,5) {
		For(i,n) v[j].pb(mp(read(),j) );
		sort(ALL(v[j]));
	}
	ll ans=0;
	Rep(j,5) {
		Rep(i,n) {
			int p=v[j][i].fi;
			vi L,R;
			
			Rep(k,5) if(k^j) {
				int l=lower_bound(ALL(v[k]),v[j][i])-v[k].begin();
				int r=v[k].end()-lower_bound(ALL(v[k]),v[j][i]);
				L.pb(l),R.pb(r);
			}
			Rep(p1,3) Fork(p2,p1+1,3) {
				ll c=mul(L[p1],L[p2]);
				Rep(t,4) if(t!=p1 && t!=p2) c=mul(c,R[t]);
				upd(ans,mul(c,p));
			}
		}
	}
	cout<<ans;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值