第一题:信(believe.cpp/c/pas)
背景描述:
一切死亡都有冗长的回声
—— 《一切》北岛
给定一个N个元素的序列A,
定义Bi = (Ai and A1) + (Ai and A2) + (Ai and A3)+ …… + (Ai and An)
定义Ci = (Ai or A1) + (Ai or A2) + … + (Ai or An)
求B和C序列。
输入格式:
第一行一个整数N表示序列长度
接下来一行N个整数, 第i个整数为Ai
输出格式:
第一行N个整数输出B序列
第二行N个整数输出C序列
样例输入:
4
3 5 1 1
样例输出:
6 8 4 4
16 22 10 10
数据规模:
对于50%的数据, N <= 1000
对于100%的数据, N <= 100000, Ai <= 100000
注意事项:
输入量较大, 请使用比较快的例如scanf的读入方式, 最好不要采用cin。
这道题嘛,水题,也有高端做法比如容斥原理。
A+B = A&B+A|B
但是就发最简单的。
em,输入量比较大,所以我不用scanf。让我们用一下读入优化。
附代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<iomanip>
#include<ctime>
#include<climits>
#include<cctype>
#include<algorithm>
#define clr(a,x) memset(x,a,sizeof(x))
#define ll long long
#ifdef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
using namespace std;
const int maxn = 100010;
ll a,n;
ll num[21],cnt[21],s[maxn],C[maxn],B[maxn];
template <class T> inline void read(T &xx)
{
xx = 0;
T flag = 1;
char ch = (char)getchar();
while(ch<'0' || ch>'9')
{
if(ch == '-') flag = -1;
ch = (char)getchar();
}
while(ch>='0' && ch<='9')
{
xx = (xx<<1) + (xx<<3) + ch - '0';
ch = (char)getchar();
}
xx *= flag;
}
ll power(ll a, ll b)
{
ll ans = 1;
while(b)
{
if(b%2 == 1)
ans = ans * a;
a = a*a;
b /= 2;
}
return ans;
}
int main()
{
freopen("believe.in","r",stdin);
freopen("believe.out","w",stdout);
read(n);
for (ll i = 1; i <= n; i++)
{
read(a);
for (ll j = 0; j <= 17; j++)
{
if((1<<j) & a) num[j]++;
else cnt[j]++;
}
s[i] = a;
}
for (ll i = 1; i <= n; i++)
{
for (ll j = 0; j <= 17; j++)
if((1<<j) & s[i])
B[i] += power(2, j) * (num[j]);
printf(AUTO" ",B[i]);
}
printf("\n");
for (ll i = 1; i <= n; i++)
{
for (ll j = 0; j <= 17; j++)
if((1<<j) & s[i])
C[i] += power(2, j) * (num[j]+cnt[j]);
else
C[i] += power(2, j) * (num[j]);
printf(AUTO" ",C[i]);
}
return 0;
}