FZU 2105 Digits Count(位数计算)
Description |
题目描述 |
Given N integers A={A[0],A[1],...,A[N-1]}. Here we have some operations: Operation 1: AND opn L R Here opn, L and R are integers. For L≤i≤R, we do A[i]=A[i] AND opn (here "AND" is bitwise operation). Operation 2: OR opn L R Here opn, L and R are integers. For L≤i≤R, we do A[i]=A[i] OR opn (here "OR" is bitwise operation). Operation 3: XOR opn L R Here opn, L and R are integers. For L≤i≤R, we do A[i]=A[i] XOR opn (here "XOR" is bitwise operation). Operation 4: SUM L R We want to know the result of A[L]+A[L+1]+...+A[R]. Now can you solve this easy problem? |
给定N个整数A={A[0],A[1],...,A[N-1]}。下面有一些操作。 操作1:AND opn L R 其中opn,L和R都是整数。 对于L≤i≤R,我们使A[i]=A[i] AND opn(这里的"AND"是位运算)。 操作2:OR opn L R 其中opn,L和R都是整数。 对于L≤i≤R,我们使A[i]=A[i] OR opn(这里的"OR"是位运算)。 操作3:XOR opn L R 其中opn,L和R都是整数。 对于L≤i≤R,我们使A[i]=A[i] XOR opn(这里的"XOR"是位运算)。 操作4:SUM L R 我们想要知道A[L]+A[L+1]+...+A[R]的值。 现在,你能解决这个简单的问题吗? |
Input |
输入 |
The first line of the input contains an integer T, indicating the number of test cases. (T≤100) Then T cases, for any case, the first line has two integers n and m (1≤n≤1,000,000, 1≤m≤100,000), indicating the number of elements in A and the number of operations. Then one line follows n integers A[0], A[1], ..., A[n-1] (0≤A[i]<16,0≤i<n). Then m lines, each line must be one of the 4 operations above. (0≤opn≤15) |
第一行有一个整数T,表示测试样例的数量。(T≤100) 后面有T个样例,每个样例的第一行有2个整数n和m(1≤n≤1,000,000, 1≤m≤100,000),表示元素数量与操作次数。 下一行有n个整数A[0], A[1], ..., A[n-1] (0≤A[i]<16,0≤i<n)。 接着m行,每行都是上述4种操作的其中一个。(0≤opn≤15) |
Output |
输出 |
For each test case and for each "SUM" operation, please output the result with a single line. |
对于每个测试样例的每个"SUM"操作,都要输出到单独的一行。 |
Sample Input - 输入样例 |
Sample Output - 输出样例 |
1 4 4 1 2 4 7 SUM 0 2 XOR 5 0 0 OR 6 0 3 SUM 0 2 |
7 18 |
【题解】
单纯的线段树。
利用线段树查找快速的特点保存元素,对于某段区间内相同状态的元素进行合并。
进行操作的时候不断查找,直到可操作的区间。因为数据都是非负整数,所以可以用负数标记元素不同的区间。
PS:状态发生变化的时候都要下压,注意深入的方向。
PS2:简单的运算速度是高于开辟空间的速度,所以没必要把线段树每个节点的左右区间都记录下来。
PSP:开辟元素数量4倍的空间一定够用。
【代码 C++】
#include<cstdio>
int data[ << ], opn, L, R;
char ts[];
int build(int data_i, int L, int R){//[L, R]
if (L == R) scanf("%d", &data[data_i]);
else{
int mid = (L + R) >> ;// [L, mid] (mid, R]
L = build(data_i << | , L, mid);
R = build(data_i + << , mid + , R);
if (L == R) data[data_i] = L;
else data[data_i] = -;
}
return data[data_i];
}
int bitwise_peration(int data_i, int L_now, int R_now){
if (data[data_i] != - && L <= L_now && R_now <= R){
if (*ts == 'A') data[data_i] &= opn;
else if (*ts == 'O') data[data_i] |= opn;
else if (*ts == 'X') data[data_i] ^= opn;
}
else{
if (data[data_i] != -) data[data_i << | ] = data[data_i + << ] = data[data_i];
int mid = (R_now + L_now) >> ;
if (R <= mid){// goto Right
L_now = bitwise_peration(data_i << | , L_now, mid);
R_now = data[data_i + << ];
}
else if (mid < L){// goto Left
L_now = data[data_i << | ];
R_now = bitwise_peration(data_i + << , mid + , R_now);
}
else{
L_now = bitwise_peration(data_i << | , L_now, mid);
R_now = bitwise_peration(data_i + << , mid + , R_now);
}
if (L_now == R_now) data[data_i] = L_now;
else data[data_i] = -;
}
return data[data_i];
}
int sum(int data_i, int L_now, int R_now){
if (data[data_i] != - && L <= L_now && R_now <= R){
return data[data_i] * (R_now - L_now + );
}
if (data[data_i] != -) data[data_i << | ] = data[data_i + << ] = data[data_i];
int mid = (R_now + L_now) >> ;
if (R <= mid) return sum(data_i << | , L_now, mid);
if (mid < L) return sum(data_i + << , mid + , R_now);
return sum(data_i << | , L_now, mid) + sum(data_i + << , mid + , R_now);
}
int main(){
int t, m, n, i;
for (scanf("%d", &t); t; --t){
scanf("%d%d", &n, &m);
--n;
build(, , n);
while (m--){
scanf("%s", ts);
if (*ts == 'S'){
scanf("%d%d", &L, &R);
printf("%d\n", sum(, , n));
}
else{
scanf("%d%d%d", &opn, &L, &R);
bitwise_peration(, , n);
}
}
}
return ;
}
#include<cstdio>
int L, R;
char data[], opn, ts[];
int read_g(){// 输入挂
int add = getchar() - '';
int a = getchar();
while (a >= '' && a <= '') add = add * + a - '', a = getchar();
return add;
}
int build(int data_i, int L, int R){// [L, R]
if (L == R) data[data_i] = read_g();
else{// [L, mid] (mid, R]
int mid = (L + R) >> ;
L = build(data_i << | , L, mid);
R = build(data_i + << , ++mid, R);
if (L == R) data[data_i] = L;
else data[data_i] = -;
}
return data[data_i];
}
int bitwise_peration(int data_i, int L_now, int R_now){
if (~data[data_i] && L <= L_now && R_now <= R){
if (*ts == 'A') data[data_i] &= opn;
else if (*ts == 'O') data[data_i] |= opn;
else if (*ts == 'X') data[data_i] ^= opn;
}
else{
if (~data[data_i]) data[data_i << | ] = data[data_i + << ] = data[data_i];
int mid = (R_now + L_now) >> ;
if (R <= mid){// goto Right
L_now = bitwise_peration(data_i << | , L_now, mid);
R_now = data[data_i + << ];
}
else if (mid < L){// goto Left
L_now = data[data_i << | ];
R_now = bitwise_peration(data_i + << , mid + , R_now);
}
else{
L_now = bitwise_peration(data_i << | , L_now, mid);
R_now = bitwise_peration(data_i + << , mid + , R_now);
}
if (L_now == R_now) data[data_i] = L_now;
else data[data_i] = -;
}
return data[data_i];
}
int sum(int data_i, int L_now, int R_now){
if (~data[data_i]){
if (L_now < L) L_now = L;
if (R < R_now) R_now = R;
return data[data_i] * (++R_now - L_now);
}
int mid = (R_now + L_now) >> ;
if (R <= mid) return sum(data_i << | , L_now, mid);
if (mid < L) return sum(++data_i << , ++mid, R_now);
return sum(data_i << | , L_now, mid) + sum(data_i + << , mid + , R_now);
}
int main(){
int m, n;
short t = read_g();
while (t--){
n = read_g(); m = read_g(); --n;
build(, , n);
while (m--){
scanf("%s", ts); getchar();
if (*ts == 'S'){
L = read_g(); R = read_g();
printf("%d\n", sum(, , n));
}
else{
opn = read_g(); L = read_g(); R = read_g();
bitwise_peration(, , n);
}
}
}
return ;
}
FZU 2105
FZU 2105 Digits Count(位数计算)的更多相关文章
- ACM: FZU 2105 Digits Count - 位运算的线段树【黑科技福利】
FZU 2105 Digits Count Time Limit:10000MS Memory Limit:262144KB 64bit IO Format:%I64d & ...
- FZU 2105 Digits Count(线段树)
Problem 2105 Digits Count Accept: 302 Submit: 1477 Time Limit: 10000 mSec Memory Limit : 262144 KB P ...
- FZU 2105 Digits Count
Problem 2105 Digits Count Accept: 444 Submit: 2139 Time Limit: 10000 mSec Memory Limit : 2621 ...
- fzu 2105 Digits Count ( 线段树 ) from 第三届福建省大学生程序设计竞赛
http://acm.fzu.edu.cn/problem.php?pid=2105 Problem Description Given N integers A={A[0],A[1],...,A[N ...
- FZU 2105 Digits Count(按位维护线段树)
[题目链接] http://acm.fzu.edu.cn/problem.php?pid=2105 [题目大意] 给出一个序列,数字均小于16,为正数,每次区间操作可以使得 1. [l,r]区间and ...
- FZU Problem 2105 Digits Count
Problem Description Given N integers A={A[0],A[1],...,A[N-1]}. Here we have some operations: Operati ...
- FOJ 2105 Digits Count
题意:对一串数字进行抑或某数,和某数,或某数,统计某区间和的操作. 思路:因为化成二进制就4位可以建4颗线段树,每颗代表一位二进制. and 如果该为是1 直接无视,是0则成段赋值为0: or 如 ...
- FZU 2105 (线段树)
Problem 2105 Digits Count Problem Description Given N integers A={A[0],A[1],...,A[N-1]}. Here we h ...
- FZU-2105 Digits Count (两种标记成段更新)
题目大意:给n个0~15之间的数,有3种更新操作,1种询问操作.3种更新操作是:1.让某个闭区间的所有数字与一个0~15之间的数字进行逻辑与运算:2.让某个闭区间的所有数字与一个0~15之间的数字进行 ...
随机推荐
- 关于oracle 11g 64位与 32位的 plsql、及其他32位应用程序共存的问题
因为 plsql 不支持 64位 oracle 客户端,所以plsql 必须使用 oracle 的 32位 instanclient 包. 解压缩后放一个目录,例如: D:\Oracle\insta ...
- yum源的修改
源路径: /etc/yum.repos.d/ 配置文件: 网络搜索 CentOS-Base.repo(默认) 设备搜索 CentOS-Media.repo 将CentOS-Base.repo移除或改名 ...
- 【secureCRT】设置自动连接会话+设置自动连接上次使用的会话:
- alias function varibales in Linux/GNU and Mac alias命令细说
细说,在古文言中是”奸细佞臣的话“,现如今成了”详细说明“的缩略. alias是MS-DOC中cmds中doskey的counterpart,是”别名“或者”化名“的意思 alias强大之处在于可以化 ...
- windows prompt personalize 设置cmd提示的相关
由于有一篇随笔种我说要引用这篇文章,所以不得已也出来了,就像你说大话『我明天去吃屎』,结果你做到了. 我这记录一下有关windows prompt这是的变量,我不知道这算不算变量,因为windows变 ...
- [转]JEXUS的高级配置
转自:http://www.cnblogs.com/xiaodiejinghong/archive/2013/04/14/3019660.html 前一回合,我们对服务器软件Jexus作了简单的介绍, ...
- 修改Linux时间一般涉及到3个命令: date, clock, hwclock
原贴:http://203.208.37.104/search?q=cache:p1vAAHvs9ikJ:www.goldthe.com /blog/%3Faction%3Dshowlog%26gid ...
- Nagios监控Oralce
一.本文说明: 本文是监控本地的Oracle,其实监控远端的Oracle也是跟下面的步骤差不多的. 二.安装Nagios.Nagios插件.NRPE软件: 安装步骤可以参考<Linux下Nagi ...
- thinkPHP3.2.3完整版 在sae上面的部署
第一步: thinkPHP3.2.3完整版,目录结构如下 第二步:在新浪sae上面创建一个新应用 第三步:用svn down,下来会有两个文件:index.php.config.ya ...
- PRINCE2七大原则(1)
PRINCE2七大原则(1) 我们先来回顾一下,PRINCE2七大原则分别是持续的业务验证,经验学习,角色与责任,按阶段管理,例外管理,关注产品,剪裁. 第二个原则:吸取经验教训. PRINCE2要求 ...