1.数组异或
(xorarray.pas/c/cpp)
(xorarray.in/out)
时间限制:2s/空间限制:256M
【题目描述】
xor——异或,和 and 与or 一样,是一种重要的逻辑运算,他的运算规律是 0 xor 0 = 0,1 xor 1 = 0,1 xor 0 = 1,0 xor 1 = 1
两个整数之间的异或是将两个整数转化成二进制,对他们的每一位分别进行 xor 操作,例:6(110) xor 13(1101) = 11(1011)
现在我们要介绍一种新的操作——数组异或,将两个相同大小(假设都为n)的数组A、B异或成一个新数组C,则新数组必满足:
现在给你数组大小n,和两个数组A,B
求他们的异或数组C
由于最终答案可能过大,你需要对C的每个元素对109+7取模
【输入格式】(xorarray.in)
一共3行。
第一行一个正整数 。
接下来两行每行 个正整数,表示数组A、B。
【输出格式】(xorarray.out)
一共 行, 个正整数,表示数组C。
【输入输出样例1】
xorarray.in xorarray.out
7
20670 1316 25227 8316 21095 28379 25235
19745 6535 14486 5460 15690 1796 12403 7583 52096 161325 276944 453024 675974 958287
【数据规模约定】
对于50% 的数据, N<=100
对于全部的数据, N<=10^5
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN = 131072;
#define Mod 1000000007
int n,A[MAXN],B[MAXN],a[32][2],b[32][2];
long long C[MAXN];
inline void read(int &x){
x=0; int f=1;char c=getchar();
while(c>'9'||c<'0'){ if(c=='-')f=-1; c=getchar(); }
while(c>='0'&&c<='9'){ x=x*10+c-'0'; c=getchar(); } x*=f;
}
int main(int argc,char *argv[]){
freopen("xorarray.in", "r", stdin);
freopen("xorarray.out", "w", stdout);
read(n);
for(int i=1; i<=n; ++i) read(A[i]);
for(int i=1; i<=n; ++i) read(B[i]);
for(int i=1; i<=n; ++i)
for(int j=0; j<=30; ++j){
++a[j][(A[i] >> j) & 1];
++b[j][(B[i] >> j) & 1];
long long c = 1LL * a[j][0] * b[j][1] + 1LL * a[j][1] * b[j][0];
if(c>=Mod) c-=Mod;
c = c * (1 << j) % Mod;
C[i] = (C[i] + c) % Mod;
}
for(int i=1; i<=n; ++i) printf("%I64d ",C[i]);
cout<<endl;
fclose(stdin); fclose(stdout);
return 0;
}
2.侦探游戏
(detective.pas/c/cpp)
(detective.in/out)
时间限制:1s/空间限制:256M
【题目描述】
小W最近沉迷一个侦探游戏,在这个游戏中会不断出现命案,而小W作为主角,需要不断地收集各种关键证据,只有当所有的关键证据都被找到,你才能驳倒所有人错误的判断,找出真正的凶手。
一共有 个关键证据以及 条信息,每条信息如下所示 : 如果你已经掌握了证据 i ,那么你可以通过 k 个时间的搜索和推理得到证据 j ,同样的,如果你掌握了证据 j 你也可以通过 k 个时间得到证据 j 。
游戏开始时玩家通过初步观察现场已经得到了证据1,于此同时,每个玩家在游戏开始阶段时都能获得一个特殊技能来加快游戏进度,增加趣味性。小 W 选了一个他以前从来没用过的技能 : 好运。这是一个被动技能,系统会在游戏开始时选定一对证据(a,b)当小W发现其中一个证据的时候,他会很好运地立即获得另外一个证据(不计入时间)。
但是这个技能是完全随机的,小W完全不知道进入游戏后系统会挑选哪一对证据,他希望你能帮助他算出他花在本轮游戏上的时间的期望值,这样他心里能有点B数。
提供的信息保证 : i不会等于j,每个k值都互不相同, 个证据都能被得到。
【输入格式】(detective.in)
一共 行。
第一行两个正整数 ,表示证据数量和信息数量。
接下来 行,每行三个数字i,j,k表示一个信息
【输出格式】(xorarray.out)
一共 行, 个整数(期望值是实数,但这里请直接保留0位小数输出)
【输入输出样例】
detective.in detective.out
3
1 2 3
1 3 2
2 3 5 2.3333
【数据规模约定】
对于20% 的数据, N<=100
对于60% 的数据, N<=1000
对于100%全部的数据, N<=20000,M<=10^5,1<= k <= 10^6
【样例解释】
答案应该是2.33333……,取2
Kusural 走一发
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
const int MAXN = 32768;
const int MAXM = 131072;
struct edge { int u, v, d; }e[MAXM];
bool operator < (const edge & a, const edge & b) {
return a.d < b.d;
}
int N, M,f[MAXN], s[MAXN];
int find(int u) {
if (f[u] == u)
return f[u];
return f[u] = find(f[u]);
}
int main() {
freopen("detective.in", "r", stdin);
freopen("detective.out", "w", stdout);
unsigned long long cnt = 0, sum = 0;
scanf("%d %d", &N, &M);
for (int i = 0; i < M; i++)
scanf("%d %d %d", &e[i].u, &e[i].v, &e[i].d);
std::sort(e, e + M);
for (int i = 1; i <= N; i++)
f[i] = i, s[i] = 1;
int tot = 0;
for (int i = 0; i < M; i++) {
int u = find(e[i].u), v = find(e[i].v);
if (u == v) continue;
sum += e[i].d;
cnt += 1ULL * s[u] * s[v] * e[i].d;
s[u] += s[v],f[v] = u;
}
double ans = sum - 2.0 * cnt / N / (N - 1);
printf("%.2lf\n", ans);
fclose(stdin);
fclose(stdout);
return 0;
}
T3
注意看书记范围,很多人的路径都是有很大一块相同的地方,做 询问分治、。
#include <cstdio>
#include <vector>
#include <bitset>
using std::vector;
using std::bitset;
const int QUERY_SIZE = 600006;
const int MAXN = 511;
int N, M, Q;
char map[MAXN][MAXN];
int ans[QUERY_SIZE];
bitset<MAXN> f[MAXN][MAXN], g[MAXN][MAXN];
struct query { int x1, y1, x2, y2, id; };
query q;
void solve(vector<query> v, int l, int r) {
int m = (l + r) >> 1;
if (l > r) return ;
for (int i = m; i >= l; i--)
for (int j = M; j >= 1; j--) {
f[i][j] = 0;
if (map[i][j] == '.') {
if (i == m) f[i][j].set(j);
else f[i][j] |= f[i + 1][j];
if (j != M) f[i][j] |= f[i][j + 1];
}
}
for (int i = m; i <= r; i++)
for (int j = 1; j <= M; j++) {
g[i][j] = 0;
if (map[i][j] == '.') {
if (i == m) g[i][j].set(j);
else g[i][j] |= g[i - 1][j];
if (j != 1) g[i][j] |= g[i][j - 1];
}
}
vector<query> vl, vr;
for (vector<query>::iterator it = v.begin(); it != v.end(); it++) {
q = *it;
if (q.x2 < m) vl.push_back(q);
else if (q.x1 > m) vr.push_back(q);
else ans[q.id] = (f[q.x1][q.y1] & g[q.x2][q.y2]).any();
}
solve(vl, l, m - 1);
solve(vr, m + 1, r);
}
int main() {
freopen("boardgame.in", "r", stdin);
freopen("boardgame.out", "w", stdout);
scanf("%d %d", &N, &M);
for (int i = 1; i <= N; i++)
scanf("%s", map[i] + 1);
vector<query> v;
scanf("%d", &Q);
for (int i = 0; i < Q; i++) {
scanf("%d %d %d %d", &q.x1, &q.y1, &q.x2, &q.y2);
q.id = i;
v.push_back(q);
}
solve(v, 1, N);
for (int i = 0; i < Q; i++)
puts(ans[i] ? "Yes" : "No");
return 0;
}