列表

详情


NC233511. Belarusian State University

描述

成为白俄罗斯国立大学 (BSU) 的学生是值得骄傲的理由。在学习算法理论课程时,您必须解决许多具有挑战性的问题,然后才能进入期末考试。这是这些问题之一。

给定一个正整数 n4n 个整数 c(i,j,k),它们可以等于 01 (, , )。

考虑介于 0 之间(包括0)的两个整数 xy。令 为它们的二进制表示 ()。定义 。显然,f(x,y) 也是 0 之间的整数。

给定两个多重集 AB,对于所有(a,b), 找到f(a,b)的值的多重集,其中

输入描述

第一行包含一个整数 

第二行包含 n4 位二进制字符串。第 i 个字符串由 以这个特定的顺序的值组成。

接下来的两行分别描述了多重集 AB。多重集的描述由 个整数 组成,表示多重集中数字 的数量()。多重集中没有其他数字。

输出描述

在单行中打印  个整数,即生成的多重集中数字  的数量。

示例1

输入:

3
0111 0110 0001
0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0

输出:

0 0 0 0 0 0 0 1

说明:

在第一个示例中,给定 56。对于 x_i, y_i \in \left\{0, 1\right\},我们有

f(x_0 + 2x_1 + 4x_2,~y_0 + 2y_1 + 4y_2) = (x_0 \text{ OR } y_0) + 2 \cdot (x_1 \text{ XOR } y_1) + 4 \cdot (x_2 \text{ AND } y_2).

因此,生成的多重集中唯一的数字是 7

示例2

输入:

2
1100 1101
2 0 2 1
2 0 2 1

输出:

2 4 3 16

示例3

输入:

1
0000
142857142 857142857
998244353 1755646

输出:

999999998000000001 0

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(clang++ 11.0.1) 解法, 执行用时: 80ms, 内存消耗: 5112K, 提交时间: 2022-08-06 19:40:35

#include<bits/stdc++.h>
using namespace std;

#define ll long long
//#define int ll

int ty[20];
template <class T>
void fwt(T f[],T g[],int ldn)
{
	int n=(1<<ldn);
	for(int ldm=1;ldm<=ldn;ldm++)
	{
		int m=(1<<ldm),mh=m>>1;
		for(int r=0;r<n;r+=m)
		{
			int t1=r,t2=r+mh;
			for(int j=0;j<mh;j++,t1++,t2++)
			{
				T u=f[t1],v=f[t2],x=g[t1],y=g[t2];
				if(ty[ldm]==0){f[t1]+=f[t2];g[t1]+=g[t2];f[t2]=g[t2]=0;}
				else if(ty[ldm]==1){f[t1]+=f[t2];g[t1]+=g[t2];}
				else if(ty[ldm]==2){f[t1]+=f[t2];swap(g[t1],g[t2]);g[t1]+=g[t2];}
				else if(ty[ldm]==3)g[t1]=g[t2]=x+y;
				else if(ty[ldm]==4){swap(f[t1],f[t2]);f[t1]+=f[t2];g[t1]+=g[t2];}
				else if(ty[ldm]==5)f[t1]=f[t2]=u+v;
				else if(ty[ldm]==6){f[t1]=u+v;f[t2]=u-v;g[t1]=x+y;g[t2]=x-y;}
				else if(ty[ldm]==7){f[t2]+=f[t1];g[t2]+=g[t1];}
				else if(ty[ldm]==8){swap(f[t1],f[t2]);swap(g[t1],g[t2]);f[t1]+=f[t2];g[t1]+=g[t2];}
				else if(ty[ldm]==9){f[t1]=u-v;f[t2]=u+v;g[t1]=x-y;g[t2]=x+y;}
				else if(ty[ldm]==10){f[t1]=f[t2]=u+v;swap(g[t1],g[t2]);}
				else if(ty[ldm]==11){swap(g[t1],g[t2]);f[t2]+=f[t1];g[t2]+=g[t1];}
				else if(ty[ldm]==12){swap(f[t1],f[t2]);g[t1]=g[t2]=x+y;}
				else if(ty[ldm]==13){swap(f[t1],f[t2]);f[t2]+=f[t1];g[t2]+=g[t1];}
				else if(ty[ldm]==14){swap(f[t1],f[t2]);swap(g[t1],g[t2]);f[t2]+=f[t1];g[t2]+=g[t1];}
				else if(ty[ldm]==15){f[t2]+=f[t1];g[t2]+=g[t1];f[t1]=g[t1]=0;}
			}
		}
	}
}

template <class T>
void ifwt(T f[],int ldn)
{
	int n=(1<<ldn);
	for(int ldm=1;ldm<=ldn;ldm++)
	{
		int m=(1<<ldm),mh=m>>1;
		for(int r=0;r<n;r+=m)
		{
			int t1=r,t2=r+mh;
			for(int j=0;j<mh;j++,t1++,t2++)
			{
				T u=f[t1],v=f[t2];
				if(ty[ldm]==0);
				else if(ty[ldm]==1)f[t1]-=f[t2];
				else if(ty[ldm]==2)f[t1]-=f[t2];
				else if(ty[ldm]==3);
				else if(ty[ldm]==4)f[t1]-=f[t2];
				else if(ty[ldm]==5);
				else if(ty[ldm]==6){f[t1]=(u+v)>>1;f[t2]=(u-v)>>1;}
				else if(ty[ldm]==7)f[t2]-=f[t1];
				else if(ty[ldm]==8)f[t1]-=f[t2];
				else if(ty[ldm]==9){f[t1]=(v-u)>>1;f[t2]=(u+v)>>1;}
				else if(ty[ldm]==10);
				else if(ty[ldm]==11)f[t2]-=f[t1];
				else if(ty[ldm]==12);
				else if(ty[ldm]==13)f[t2]-=f[t1];
				else if(ty[ldm]==14)f[t2]-=f[t1];
				else if(ty[ldm]==15)continue;
			}
		}
	}
}

// will **change** f[] and g[], result is stored in f[]
template <class T>
void convolution(T f[],T g[],int n)
{
	int ldn=__lg(n);assert((1<<ldn)==n);
	fwt(f,g,ldn);
	for(int i=0;i<n;i++)f[i]=f[i]*g[i];
	ifwt(f,ldn);
}
char s[10];
ll f[300005],g[300005];

void solve()
{
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%s",s+1);
		for(int j=1;j<=4;j++)
		{
			if(s[j]=='1')(ty[i]<<=1)|=1;
			else ty[i]<<=1;
		}
	}
	for(int i=0;i<(1<<n);i++)scanf("%lld",&f[i]);
	for(int i=0;i<(1<<n);i++)scanf("%lld",&g[i]);
	convolution(f,g,(1<<n));
	for(int i=0;i<(1<<n);i++)printf("%lld%c",f[i]," \n"[i==(1<<n)-1]);
}

signed main()
{
//	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);



//	int _;scanf("%lld",&_);while(_--)
		solve();
	return 0;
}

C++(g++ 7.5.0) 解法, 执行用时: 776ms, 内存消耗: 5204K, 提交时间: 2022-11-02 00:12:12

#include<bits/stdc++.h>
using namespace std;

using ll = long long;
using pll = pair<ll, ll>;

constexpr int maxn = 18;

ll a[1<<maxn], b[1<<maxn];
vector<string>func;

pll A(string s, ll x, ll y){
	if(s=="0000") return {x+y, 0};
	if(s=="0001") return {x+y, y};
	if(s=="0010") return {x+y, y};
	if(s=="0011") return {x,   y};
    if(s=="0100") return {x+y, x};
    if(s=="0101") return {x+y, x+y};
    if(s=="0110") return {x+y, x-y};
    if(s=="0111") return {x, x+y};
    if(s=="1000") return {x+y, x};
    if(s=="1001") return {x+y, x-y};
    if(s=="1010") return {x+y, x+y};
    if(s=="1011") return {x, x+y};
    if(s=="1100") return {y,   x};
    if(s=="1101") return {y, x+y};
    if(s=="1110") return {y, x+y};
    if(s=="1111") return {0, x+y};
    return {0,0};
}

pll B(string s, ll x, ll y){
	if(s=="0000") return {x+y, 0};
	if(s=="0001") return {x+y, y};
	if(s=="0010") return {x+y, x};
    if(s=="0011") return {x+y, x+y};
    if(s=="0100") return {x+y, y};
    if(s=="0101") return {x,   y};
    if(s=="0110") return {x+y, x-y};
    if(s=="0111") return {x, x+y};
    if(s=="1000") return {x+y, x};
    if(s=="1001") return {x+y, x-y};
    if(s=="1010") return {y,   x};
    if(s=="1011") return {y, x+y};
    if(s=="1100") return {x+y, x+y};
    if(s=="1101") return {x, x+y};
    if(s=="1110") return {y, x+y};
    if(s=="1111") return {0, x+y};
    return {0,0};
}

pll inv_C(string s, ll x, ll y){
	if(s=="0000") return {x,   y};
	if(s=="0001") return {x-y, y};
	if(s=="0010") return {x-y, y};
	if(s=="0011") return {x,   y};
    if(s=="0100") return {x-y, y};
    if(s=="0101") return {x,   y};
    if(s=="0110") return {(x+y)/2, (x-y)/2};
    if(s=="0111") return {x, y-x};
    if(s=="1000") return {x-y, y};
    if(s=="1001") return {(x-y)/2, (x+y)/2};
    if(s=="1010") return {x,   y};
    if(s=="1011") return {x, y-x};
    if(s=="1100") return {x,   y};
    if(s=="1101") return {x, y-x};
    if(s=="1110") return {x, y-x};
    if(s=="1111") return {x, y};
    return {0,0};
}

void fwht(ll f[], int n, pll (*trans)(string s, ll x, ll y)){
	int len = 1<<n;
    for(int bit = 0, step = 1; step < len ; bit++, step *= 2){
    	for(int i = 0 ; i < len ; i += step*2){
    		for(int j = i ; j < i + step ; j ++){
    			auto x = f[j], y = f[j+step];
    			tie(f[j], f[j+step]) = trans(func[bit], x, y);
    		}
    	}
    }
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);

	int n; cin >> n;
	func.resize(n);
	for(int i = 0 ; i < n ; i ++) cin >> func[i];

	for(int i = 0 ; i < (1<<n) ; i ++) cin >> a[i];
	for(int i = 0 ; i < (1<<n) ; i ++) cin >> b[i];

	fwht(a, n, A), fwht(b, n, B);
    for(int i = 0 ; i < (1<<n) ; i ++) a[i] *= b[i];
    fwht(a, n, inv_C);

    for(int i = 0 ; i < (1<<n) ; i ++) cout << a[i] << " \n"[i==(1<<n)-1];

	return 0;
}

上一题