World Finals 2024 Upsolving

J/S

// what is matter? never mind. 
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
//#pragma GCC target("sse,sse2,sse3,sse4,popcnt,abm,mmx,avx,avx2") 
#include<bits/stdc++.h>
#define For(i,a,b) for(int i=(a);i<=(b);++i)
#define Rep(i,a,b) for(int i=(a);i>=(b);--i)
#define ll long long
#define int long long
#define ull unsigned long long
#define SZ(x) ((int)((x).size()))
#define ALL(x) (x).begin(),(x).end()
using namespace std;
inline int read()
{
    char c=getchar();int x=0;bool f=0;
    for(;!isdigit(c);c=getchar())f^=!(c^45);
    for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+(c^48);
    if(f)x=-x;return x;
}

#define fi first
#define se second
#define pb push_back
#define mkp make_pair
typedef pair<int,int>pii;
typedef vector<int>vi;
 
#define maxn 10005
#define inf 0x3f3f3f3f3f3f3f3f

int n,c,a[maxn],up;
int sum[maxn];

int w(int j,int i){
	return sum[j]+a[i];
}
int f[10005][10005];

signed main()
{
	n=read(),c=read();
	For(i,1,n)a[i]=read();
	sort(a+1,a+n+1);
	if(n<=c)cout<<a[n],exit(0);
	
	For(i,1,n)sum[i]=sum[i-1]+a[i];
	up=n/c;
	For(i,0,n)For(j,0,up)f[i][j]=inf;
	
	f[0][0]=0;
	For(i,1,n){
//		cout<<"i: "<<i<<"\n";
		if(i<=c) f[i][0]=min(f[i][0],w(0,i));
		For(j,0,(n-i)/c+1){
			For(k,0,j+1){
				if(k>c) break;
				// 1....i   -> j<-
				if(i>=c+1 && i-(c-k)>=0 && k<c)
					f[i][j]=min(f[i][j],w(k,i)+f[i-(c-k)][j-(k-1)]);
				// 1..k  + (l..i) --> , 1...k <--
				if(i<=c && k>=1 && k<=c)
					f[i][j]=min(f[i][j],w(k,i)+f[k][j-(k-1)]);
				// 1..i -->, 1..k <--- , 1..k -->
				
			}
		}
		
//		For(j,0,up){
//			cout<<f[i][j]<<" ";
//		}cout<<"\n";
		
	}
	cout<<f[n][0];
	return 0;
}
/*
4 2
1 2 5 10
7 2
1 2 4 5 7 10 14
7 3
2 2 2 3 6 6 6
*/

Z:

// what is matter? never mind. 
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
//#pragma GCC target("sse,sse2,sse3,sse4,popcnt,abm,mmx,avx,avx2") 
#include<bits/stdc++.h>
#define For(i,a,b) for(int i=(a);i<=(b);++i)
#define Rep(i,a,b) for(int i=(a);i>=(b);--i)
#define ll long long
#define int long long
#define ull unsigned long long
#define SZ(x) ((int)((x).size()))
#define ALL(x) (x).begin(),(x).end()
using namespace std;
inline int read()
{
    char c=getchar();int x=0;bool f=0;
    for(;!isdigit(c);c=getchar())f^=!(c^45);
    for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+(c^48);
    if(f)x=-x;return x;
}

#define fi first
#define se second
#define pb push_back
#define mkp make_pair
typedef pair<int,int>pii;
typedef vector<int>vi;

#define maxn 200005
#define inf 0x3f3f3f3f

int n,k,T,pw[23];

int tox(char c){
	if(c=='A')return 0;
	if(c=='E')return 1;
	if(c=='I')return 2;
	exit(233);
}
char toc(int x){
	if(x==0)return '0';
	if(x==1)return '+';
	if(x==2)return '-';
}

struct node{
	int f[3];
	node(){
		memset(f,0,sizeof f);
	}
	int &operator [](int x){
		return f[x];
	}
	void simp(){
		f[1]-=f[0],f[2]-=f[0];
		f[0]=0;
	}
	void out(){
		cout<<f[0]<<" "<<f[1]<<' '<<f[2]<<'\n';
	}
	void simp2(){
		if(f[1] && f[2]) f[0]=-f[1],f[1]=f[2]=0;
	}
};
node operator +(node a,node b){
	For(i,0,2)a[i]+=b[i];
	a.simp();return a;
}
node operator *(node a,node b){
	node c;
	For(i,0,2)For(j,0,2)c[(i+j)%3]+=a[i]*b[j];
	c.simp();return c;
}

int add(int x,int y){
	int z=0;
	For(i,0,k-1){
		int xx=x/pw[i]%3,yy=y/pw[i]%3;
		z+=pw[i]*((xx+yy)%3);
	}
	return z;
}
int neg(int x){
	int z=0;
	For(i,0,k-1){
		int xx=x/pw[i]%3;
		z+=pw[i]*((3-xx)%3);
	}
	return z;
}
int sub(int x,int y){
	return add(x,neg(y));
}
int dot(int x,int y){
	int res=0;
	For(i,0,k-1){
		int xx=x/pw[i]%3,yy=y/pw[i]%3;
		res+=xx*yy%3;
	}
	return res%3;
}

int in(){
	string s; cin>>s;
	int x=0;
	For(i,0,k-1) x+=tox(s[i])*pw[i];
	return x;
}
void out(int x){
	For(i,0,k-1) putchar(toc(x/pw[i]%3));
	puts("");
}

int dt[505][505];
int cnt[505];
node f[505];
int c0[505];
node I1,I2;

int col[505];
int ans[505],len,res[505];
int sta[505],sta2[505];

int qwq[505];
int fs[505],gs[505];

bool chk(){
//	For(i,0,n-1)cout<<res[i]<<" "; cout<<"\n";
//	For(i,0,n-1){
//		int sum0=0,sum=0;
//		For(j,0,n-1){
//			if(dt[i][res[j]]==0) sum0+=1;
//			else sum+=dt[i][res[j]];
//		}
//		if(sum0!=c0[i]) puts("QWQ"),exit(23333);
//		sum=(sum%3+3)%3;
//	//	cout<<"sum "<<i<<" "<<sum<<"\n";
//		if(sum!=col[i])return 0;
//	}
//	For(i,0,n-1) cout<<res[i]<<" "; cout<<"\n";
//	memset(qwq,0,sizeof qwq);
//	For(s,0,(1<<n)-1){
//		int x=0;
//		For(i,0,n-1)if(s>>i&1)x=add(x,res[i]);
//		qwq[x]++;
//	}
//	For(i,0,pw[k]-1){
//		cout<<"i: "<<i<<" "<<cnt[i]<<" "<<qwq[i]<<"\n";
//	}
	For(i,0,pw[k]-1) fs[i]=0; fs[0]=1;
	For(i,0,n-1){
		For(s,0,pw[k]-1) gs[add(s,res[i])]+=fs[s];
		For(s,0,pw[k]-1) fs[s]+=gs[s],gs[s]=0;
	}
	For(s,0,pw[k]-1) if(fs[s]!=cnt[s]) return 0;
	return 1;
}

signed main()
{
	I1.f[1]=I2.f[2]=1;
	n=read(),k=read(),T=read();
	pw[0]=1; For(i,1,k)pw[i]=pw[i-1]*3;
	For(i,0,pw[k]-1) For(j,0,pw[k]-1) dt[i][j]=dot(i,j);
	
	For(i,1,T){
		int x=in(),y=read();
		cnt[x]+=y;
		f[x][0]+=y;
	}
	For(i,0,k-1){
		For(s,0,pw[k]-1)
			if(s/pw[i]%3==0){
				node &f0=f[s],&f1=f[s+pw[i]],&f2=f[s+pw[i]*2];
				node g0=f0+f1+f2;
				node g1=f0+f1*I2+f2*I1;
				node g2=f0+f1*I1+f2*I2;
			//	g0.out(),g1.out(),g2.out();
				f0=g0,f1=g1,f2=g2;
			}
	}
	For(s,0,pw[k]-1){
		f[s].simp();
		f[s].simp2();
		col[s]=-1;
		For(i,0,2) if(f[s][i]) col[s]=i;
	//	cout<<"col "<<s<<" "<<col[s]<<"\n";
	//	For(i,0,2) cout<<f[s][i]<<" ";
	//	cout<<"\n";
		int sum=abs(f[s][0]+f[s][1]+f[s][2]);
		For(j,0,n) if((1ll<<j)==sum) c0[s]=j;
	}
	// find one sol
	// f[s] = \sum dot(s,t)==0 cnt[t]
	Rep(i,pw[k]-1,0){
		while(1){
			int sum[3]={0,0,0};
			For(j,0,pw[k]-1){
				sum[dt[i][j]]+=c0[j];
			}
			if(sum[0]==sum[1]) break;
		//	cout<<"i: "<<i<<"\n";
		//	For(j,0,2) cout<<sum[j]<<" "; cout<<"\n";
		//	break;
			ans[len++]=i;
		//	cout<<"add "<<i<<"\n";
			For(j,0,pw[k]-1)
				if(dt[i][j]==0) c0[j]--;
		}
	}
	assert(len==n);
	memset(sta,-1,sizeof sta);
	memset(sta2,-1,sizeof sta2);
	sta[0]=0;
	For(i,0,n-1){
		For(s,0,pw[k]-1) if(sta[s]!=-1) {
			int t=add(s,ans[i]);
			if(sta[t]==-1)
				sta2[t]=sta[s]^(1ll<<i);//cout<<"to "<<t<<" "<<sta2[t]<<"\n";
		}
		For(s,0,pw[k]-1)
			if(sta[s]==-1 && sta2[s]!=-1) sta[s]=sta2[s];
	}
	For(s,0,pw[k]-1)
		if(sta[s]!=-1){
		//	cout<<"chk "<<s<<" "<<sta[s]<<"\n";
			For(i,0,n-1) res[i]=(sta[s]>>i&1)?neg(ans[i]):ans[i];
			if(chk()){
				For(i,0,n-1) out(res[i]);
				break;
			}
		}
	return 0;
}
/*
2 3 1
AAA 4

2 3 4
EEE 1
EIA 1
IAE 1
AAA 1
*/

E:

太垃圾,不写了。

posted @ 2024-04-20 20:25  Rainbow_qwq  阅读(102)  评论(0编辑  收藏  举报