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之间的数字进行 ...
随机推荐
- (顺序表的应用5.4.2)POJ 1591 M*A*S*H(约瑟夫环问题的变形——变换步长值)
/* * POJ_1591_2.cpp * * Created on: 2013年10月31日 * Author: Administrator */ #include <iostream> ...
- android 项目学习随笔一(闪屏 )
1.取标题栏且全屏 <activity android:name="com.ecollab.zhsh66.SplashActivity" android:label=&quo ...
- Centos7 安装配置NFS
一.安装 NFS 服务器所需的软件包 # yum install -y nfs-utils 二.编辑exports文件 # vim /etc/exports /data/disk1/video *(a ...
- 如何为github上的项目添加gif效果图
一.制作gif图片 如何制作可以参考: http://www.jianshu.com/p/27ec6375b8ab?utm_campaign=maleskine&utm_content=not ...
- sql必知必会(第四版) 学习笔记
还有一个<Sqlserver2008技术内幕>的笔记,也很好!~ http://www.cnblogs.com/liupeng61624/p/4354983.html 温习一遍简单的sql ...
- 更改printk打印级别
1.查看当前控制台的打印级别 cat /proc/sys/kernel/printk 4 4 1 7 其中第一个"4"表示内核打印函数printk的打印级别,只有 ...
- c# 服务端
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- WCF自定义地址路由映射(不用svc文件)
一般在创建WCF服务时会用Serivce.svc文件访问,地址如:http://localhost/applicationname/Serivce.svc/Name 现在用路由映射成:http://l ...
- Winsock系列函数 及 Socket通信流程
Socket是一种网络通信机制 Winsock系列函数 1. Socket 创建socket 2. Connect 尝试连接远端Socket 3. Send 在某个Socket 向远端 ...
- HashMap, HashTable, CurrentHashMap的区别
转载:http://www.jianshu.com/p/c00308c32de4 HashMap vs ConcurrentHashMap 引入ConcurrentHashMap是为了在同步集合Has ...