2016 华科校赛 B. And

// 2016 华科校赛 B. And

http://acm.hust.edu.cn/problem/show/1672

题目描述

给出 a[1], ..., a[n]。查询 t[1], ... t[m],问有多少 a[] 的子序列的按位与是 t[]。

输入

多组测试,EOF 结束。

n
a[]
m
t[]

1 ≤ n ≤ 1e6

1 ≤ m ≤ (1 << 20)

1 ≤ a[i] ≤ (1 << 20)

1 ≤ t[i] ≤ (1 << 20)

输出

输出一行,每组查询输出一个数,每个数后面一个空格。

来源

sheep

思路

先膜拜一会儿……【三分钟之后】好了开始讲题解。

用分治的思想解决。目的是对于给定的a[],处理出一个数组ans[]。ans[x]的值就是按位与是x的子序列的数目。

考查这个问题的输入和输出,我们建立这样一个分治模型:void work(int cnt[LEN], int ans[LEN]);。其中cnt[]是输入,ans[]是输出。cnt[x]表示a[]中有多少个x;ans[x]表示有多少子序列按位与结果是x。LEN是当前值区间的长度,也就是说当前的wrok解决的问题是[0, LEN)范围内的结果。

对一个取值区间[0, 2L)分析解,最后答案就是[0, 1<<20)的解。

我们发现较大的一半[L, 2L)是容易解决的,因为这里面的数最高位是1,要按位与结果是这里面的数,选择的数也一定得在这个范围内才行(选择了一个[0, L)内的数之后,按位与最高位就是0了)。所以这个部分可以递归使用work解决,具体方法是 work(cnt1[], ans1[]),cnt1[i]是cnt[i + L];ans1[i]将是ans[i + L]。

但是较小的一半是不容易解决的,对i ∈ [0, L),可以选择[0, L)中的数,也可以选择[L, 2L)中的,只要最高位的1被与掉了就可以。既然如此我们不妨考虑整体,不直接计算ans[i],而计算ans[i] + ans[i + L]。这个值的意义就是,无视最高位是多少,按位与的结果的剩下的部分是i的子序列数目。无视最高位,只要把cnt[i]和cnt[i + L]也就是一样的数。调用的方法是work(cnt2[], ans2[]),这里的cnt2[i] = cnt[i] + cnt[i + L],ans2[i]将是ans[i] + ans[i + L]。

分完这两部分,就可以解决ans[]的计算了,对于i ∈ [L, 2L),ans[i] = ans1[i - L];对于i ∈ [0, L),ans[i] = ans2[i] - ans1[i]。

时间: 2024-10-13 23:50:50

2016 华科校赛 B. And的相关文章

2016 SCNUCPC 校赛非官方题解

我要举报本次校赛出题人的消极出题!!! A. 树链剖分数据结构板题 B. The background of water problem 题目大意(大写加粗的水题):给定$N$个学生和他们$K$个科目的成绩$S_i$,再给出各科目$K_i$的权重顺序$Q_i$,求排名之后,拥有id为$X$的是哪个学生. 基本思路:虽然$K$只有$10$,$S$只有$100$,但有M组查询,所以当然不能开个long long去hash每个学生.我们简单点,开个结构体,排个序,就好了. 参考代码: 官方代码(将成绩

Fire Air(华科校赛 网络赛)

题目 原题链接:https://www.nowcoder.com/acm/contest/106/L 在100000 * 10000的空地上,有n个时间点,每个时间点会在(xi,yi)上种一棵树. 定义绿色:被树包围的空地的个数. 问每个时间点之后绿色为多少.如图: 思路 逆向求解,从(0,0)位置将圈外的全标记(给空地加一圈),在分别考虑当前的树,是在圈内还是圈的外围. 由于vis是全局数组,之后的bfs都非常快,每个点只遍历过一次. 代码实现 1 #include<stdio.h> 2 #

kmp变形,带通配符的kmp——华科校赛E 好题

https://blog.csdn.net/a302549450/article/details/80948741?tdsourcetag=s_pctim_aiomsg 上面是题解的链接.., #include<cstdio> #include<iostream> #include<algorithm> #include<cmath> #include<cstring> #include<string> #include<map

2016 年宁波工程学院第七届ACM校赛题解报告

2016 年宁波工程学院第七届ACM校赛题解报告 本题解代码直接为比赛代码,仅供参考. A,B,C,D,G,H,J,K,L,M 来自 Ticsmtc 同学. F 来自 Gealo 同学. E,I 来自Alex 学长. Promblem A :    Two Sum 时间限制: 1 Sec  内存限制: 64 MB 题目描述: 给出n个数,另外给出?个整数S,判断是否可以从中取出2个数,使得这两个数的和是S. 输入: 第?行有个整数T(1 <= T <= 10),代表数据组数. 对于每组数据,第

CSU 1425 NUDT校赛 I题 Prime Summation

这个题本来有希望在比赛里面出了的 当时也想着用递推 因为后面的数明显是由前面的推过来的 但是在计算的时候 因为判重的问题 ...很无语.我打算用一个tot[i]来存i的总种树,tot[i]+=tot[j]//j为可以由j推到i的一系列数,但这样是不对的,会产生大量重复计算... 看了下标程才发现要用二维来计算出种类总数,f[i][j]+=sum(f[i-j][k]) 表示在推i数的时候,第一个素数为j的种类数,注意j一定为素数,而且k不能大于j...标程里面处理的比较简练,就学了下他的写法. 至

校赛总结

写写校赛总结....... 这两次校赛是我们组队以后第一次的比赛...第一场打得很拙,第二场还可以吧,第一场校赛--毕竟是期待了很久的校赛,所以感觉还是很紧张,吃饭的时候打了二两,剩了一大半==, 这次我们队名叫 I_Love_High_Math......没走到现场,就快下雨了,真的有点郁闷==.到了以后下雨了,和一个队友被困雨中,,出来以后衣服湿了,一开始就悲剧了...     然后一开场就感觉不好.比赛开始的时候,我去写头文件,然后W说A是水题,然后叫我写,平时都是我写第一题的这次我不想开

NYOJ-682 小媛在努力 (郑大第六届校赛 模拟)

链接:click here 题意: 描述 在多媒体数据处理中,数据压缩算法尤为重要.小媛上完课后就想自己发明一个数据压缩算法.她想呀想,终于想到一个方法.在多媒体数据中有很多数据都是重复的,所以她想把连续相同的数据用数据出现的次数和数据本身表示.例如:1 1 1 2 3 3 3 3 3  压缩后及为3 1 1 2 5 3(表示3个1,1个2和5个3).有想法后小媛就希望把它用代码实现了.但是大家都知道小媛现在整天都忙着苦B的复习考研,连电脑都摸不到.所以她希望作为ACMer的你帮她写一下. 输入

HDU多校赛第9场 HDU 4965Fast Matrix Calculation【矩阵运算+数学小知识】

难度上,,,确实,,,不算难 问题是有个矩阵运算的优化 题目是说给个N*K的矩阵A给个K*N的矩阵B(1<=N<=1000 && 1=<K<=6),先把他们乘起来乘为C矩阵,然后算C^(N*N) 相当于 ABABABABABABAB...=(AB)^(N*N) 不如 A(BA)^(N*N-1)B 因为BA乘得K*K的矩阵,K是比较小的 #include <cstdio> #include <cstdlib> #include <cstr

ZJU校赛 一道计数题

题意是这样的 给定一个n*m的整数矩阵 n和m均小于1000 对这个矩阵删去任意行和列后剩余一个矩阵为M{x1,x2,,,,xm;y1,y2,,,,,yn}表示删除任意的M行N列 对于这个剩下的矩阵,我们考虑其中是否存在特殊的元素,保证这些元素是所在行最大,所在列最小的元素 且非之一. 求对于所有删法,上述元素个数之和 对10^9+7取余. 显然所有删法 有2^(n+m)种 暴力是搞不定的. 于是反过来看,矩阵的元素最多有10^6个 是不是可以考虑每一个元素对最终答案的贡献? 所谓贡献,就是它在