Binary

Description

这里写图片描述

Data Constraint

这里写图片描述

Solution

这道题部分分很好的提示了我们该怎么做。对于另外20%的数据,x=0的情况,很显然要把每个数按二进制一位一位拆开来做。因为and运算是每一位独立的,注意到ai,x,y<220,所以我们可以开个数组(F[0..20])存每一个二进制位1的个数,那么对于每个询问,如果y在二进制下第i位是1,答案就加上F[i]*2i1
那么这该怎么拓展到全部数据呢。我们开个树状数组Tri[i][j],i:1~20,表示每个二进制位的树状数组,j表示的是每个数mod 2i(即每个数二进制下后i位),树状数组存的就是j出现的次数。每次修改就把a[x]对应的都-1,y的+1。而询问,如果y在二进制下第i位是1,那么对于Tri[i][j],我们要查询的j就是[L,R],L=2i1-xR=2i-1-x,这里的x是mod了2i的,因为L有可能小于零,所以L=(L+2i) mod 2i,而这样一来,L就有可能大于R了。当L<=R,Ans=Ans+(Find(i,R)-Find(i,L-1)) * 2i1;当L>R,Ans=Ans+(Find(i,R)+Find(i,2i)-Find(i,L-1)) * 2i1。然后就可以了。

Code

Const
    Maxn=100005;
    Num=1100000;

Var
    n,m:Longint;
    a:Array[0..Maxn] OF Longint;
    f:Array[0..20,0..Num] OF Int64;

Function Lowbit(x:Longint):Longint;
Begin
    Exit(x And (-x));
End;

Procedure Inse(k,x:Longint);
Var
    Mx:Longint;
Begin
    Mx:=1 << k;
    While x<=Mx Do
    Begin
        Inc(f[k][x]); Inc(x,Lowbit(x));
    End;
End;

Procedure Init();
Var
    i,j:Longint;
Begin
    Readln(n,m);
    For i:=1 To n Do
    Begin
        Read(a[i]);
        For j:=1 To 20 Do Inse(j,a[i] Mod (1 << j)+1);
    End;
End;

Procedure Dele(k,x:Longint);
Var
    Mx:Longint;
Begin
    Mx:=1 << k;
    While x<=Mx Do
    Begin
        Dec(f[k][x]); Inc(x,Lowbit(x));
    End;
End;

Procedure Change(x,y:Longint);
Var
    i:Longint;
Begin
    For i:=1 To 20 Do
    Begin
        Inse(i,y Mod (1 << i)+1); Dele(i,a[x] Mod (1 << i)+1);
    End;
    a[x]:=y;
End;

Function Find(k,x:Longint):Int64;
Begin
    Find:=0;
    While x>0 Do
    Begin
        Inc(Find,f[k][x]); Dec(x,Lowbit(x));
    End;
End;

Function Get(x,y:Longint):Int64;
Var
    i,l,r,t,Mo:Longint;
    Tot:Int64;
Begin
    Get:=0;
    For i:=1 To 20 Do
    Begin
        If y And (1 << (i-1))=0 Then Continue;
        Mo:=1 << i; t:=x Mod Mo;
        l:=(1 << (i-1)-t+Mo) Mod Mo; r:=Mo-1-t;
        Tot:=Find(i,r+1)-Find(i,l);
        If Tot<0 Then Tot:=Tot+Find(i,Mo);
        Get:=Get+Tot*(1 << (i-1));
    End;
End;

Procedure Main();
Var
    k,x,y:Longint;
Begin
    For m:=m Downto 1 Do
    Begin
        Readln(k,x,y);
        If k=1 Then Change(x,y) Else Writeln(Get(x,y));
    End;
End;

Begin
    //Assign(Input,'binary.in'); Reset(Input);
    //Assign(Output,'binary.out'); Rewrite(Output);

    Init();
    Main();

    //Close(Input); Close(Output);
End.
05-10
<think>好的,我现在需要处理用户关于COBOL中BINARY数据类型的问题。首先,用户之前问了关于PIC X(10)和PIC 9(10)的区别,现在接着问BINARY的用法,说明他们在学习COBOL的数据类型,可能需要更深入的理解数值存储方式。 用户提到参考了之前的引用,但引用[1]和[2]似乎和当前问题关联不大,所以我应该专注于用户的实际问题,即BINARY的定义和使用场景。根据之前的知识,COBOL中的BINARY通常与数值存储相关,特别是二进制格式,可能用于优化性能或节省空间。 首先,我需要确认BINARY在COBOL中的具体定义。可能涉及到USAGE子句,比如USAGE IS BINARY或COMP-0、COMP-4等。需要解释这些术语,以及它们如何影响数据存储和计算效率。 然后,使用场景方面,用户可能想知道何时使用BINARY而不是其他格式,比如PIC 9的DISPLAY或COMP-3。这时候需要比较不同存储方式的优缺点,比如存储空间、计算速度、兼容性等。 还要考虑用户可能的实际应用,比如处理整数、性能敏感的应用,或者与其他系统的交互。需要举例说明,比如定义字段为BINARY,并展示代码示例,帮助用户理解如何在实际代码中使用。 另外,用户可能对BINARY的长度和取值范围有疑问,需要解释不同字节长度对应的数值范围,比如半字长、全字长、双字长,以及如何根据需求选择合适的大小。 最后,要确保回答结构清晰,分点说明定义、语法、存储特性、应用场景以及注意事项,并附上示例代码,这样用户能逐步理解。同时,检查是否有遗漏点,比如是否支持符号位,不同编译器之间的差异,以及可能的性能提升情况。</think>### COBOL中`BINARY`数据类型的定义与使用场景解析 在COBOL中,`BINARY`是一种数值存储格式,通过`USAGE`子句定义,用于优化数值计算效率和存储空间。以下是其核心要点: --- #### 1. **定义与语法** - **`BINARY`** 是数值字段的二进制存储方式,需与`PIC 9`配合使用。 - **语法示例**: ```cobol 01 COUNTER PIC S9(9) USAGE BINARY. *> 定义带符号的4字节二进制整数 01 QUANTITY PIC 9(4) USAGE COMP. *> COMP等同于BINARY(部分编译器) ``` - `COMP`或`COMP-4`是`BINARY`的同义词(具体取决于编译器)[^1]。 --- #### 2. **存储特性** | 特性 | `BINARY`(二进制格式) | 对比`DISPLAY`(默认文本格式) | |---------------------|--------------------------------------|-------------------------------------| | **存储方式** | 二进制补码形式(直接内存存储) | ASCII字符(每位占1字节) | | **空间占用** | 紧凑(如4字节存储9位数字) | 冗余(10字节存储10位数字) | | **计算效率** | 高(直接参与CPU运算) | 低(需转换为二进制再计算) | | **符号处理** | 支持带符号(`PIC S9`) | 符号单独占用一个字节 | --- #### 3. **典型使用场景** - **高性能计算** 需要频繁参与数学运算的字段(如计数器、金额汇总): ```cobol 01 TOTAL-SALES PIC S9(9)V99 USAGE BINARY. *> 高效处理销售额累加 ``` - **节省存储空间** 大型数值数据集(如库存数量、交易流水号): ```cobol 01 ITEM-COUNT PIC 9(7) USAGE BINARY. *> 仅需4字节存储百万级数值 ``` - **与其他系统交互** 与C、Java等语言编写的系统交换二进制数据时保持兼容性[^3]。 --- #### 4. **字节长度与取值范围** | `PIC`定义 | 字节长度 | 取值范围(无符号) | 取值范围(有符号) | |---------------------|----------|--------------------|--------------------------| | `PIC 9(4) BINARY` | 2字节 | 0 ~ 65,535 | -32,768 ~ +32,767 | | `PIC 9(9) BINARY` | 4字节 | 0 ~ 4,294,967,295 | -2,147,483,648 ~ +2,147,483,647 | | `PIC 9(18) BINARY` | 8字节 | 0 ~ 18,446,744,073,709,551,615 | -9,223,372,036,854,775,808 ~ +9,223,372,036,854,775,807 | --- #### 5. **注意事项** 1. **字段长度限制** `BINARY`字段的位数需与字节长度匹配(例如,`PIC 9(4)`对应2字节,最多存储4位数字)。 2. **符号处理** 若定义`PIC S9(n)`,最高位为符号位(0正1负),需预留足够位数。 3. **编译器差异** IBM COBOL中`COMP-4`等价于`BINARY`,而Micro Focus COBOL可能默认`COMP`为二进制格式。 --- ### 总结 `BINARY`在COBOL中通过二进制存储优化数值运算效率,**适用于高频计算、大容量数据或跨系统交互的场景**。选择时需权衡存储空间、性能需求和数据精度[^1][^3]。 --- ### 相关问题 1. COBOL中`COMP-3`与`BINARY`有何区别? 2. 如何定义COBOL中的浮点数字段? 3. `BINARY`字段在文件读写时需要注意哪些兼容性问题?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值