国庆清北刷题冲刺班 Day6 下午

53 篇文章 1 订阅
51 篇文章 0 订阅

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

七情六欲·

学生党不容易~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值