HDU 1556 BIT区间修改+单点查询(fread读入优化)

BIT区间修改+单点查询

【题目链接】BIT区间修改+单点查询

&题解:

BIT区间修改+单点查询和求和的bit是一模一样的(包括add,sum) 只不过是你使用函数的方式不一样:
使用区间的时候,比如[a,b]区间+1,就是add(a,1); add(b+1,-1); 之后sum(i)查的是i点的值,是一个i点的值,不是区间!!
另外,主函数中fread()必须调用2句话,因为它是缓冲的,所以不可以边输入边测试,只能用freopen测试, 另外附上时间比较,第一个是用的fread,第二个是没用
942601-20170716111327175-1463897475.png
942601-20170716111348832-1379463612.png
我还测了一下getchar()的读入挂,结果是780ms,比scanf还慢点,总感觉那个挂没什么用哦
942601-20170716112129660-1763319296.png

&代码:

#include <cstdio>
#include <bitset>
#include <iostream>
#include <set>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <map>
#include <queue>
#include <vector>
using namespace std;
#define INF 0x3f3f3f3f
#define ll long long
#define fo(i,a,b) for(int i=(a);i<=(b);i++)
#define fd(i,a,b) for(int i=(a);i>=(b);i--)
#define cle(a,v) memset(a,(v),sizeof(a))
const int maxn = 100000 + 7;

//Reading Plugin
const int BUF = 20000000;
char Buf[BUF], *buf = Buf;
const int OUT = 10000000;
char Out[OUT], *ou = Out; int Outn[30], Outcnt;
inline void write(int x) {
    if(!x)*ou++ = 48;
    else {
        for(Outcnt = 0; x; x /= 10)Outn[++Outcnt] = x % 10 + 48;
        while(Outcnt)*ou++ = Outn[Outcnt--];
    }
}
inline void writell(ll x) {
    if(!x)*ou++ = 48;
    else {
        for(Outcnt = 0; x; x /= 10)Outn[++Outcnt] = x % 10 + 48;
        while(Outcnt)*ou++ = Outn[Outcnt--];
    }
}
inline void writechar(char x) {*ou++ = x;}
inline void writeln() {*ou++ = '\n';}
inline void read(int&a) {for(a = 0; *buf < 48; buf++); while(*buf > 47)a = a * 10 + *buf++ -48;}


int n, a, b;
struct BIT {
    int n, bit[maxn];
    void ori(int _n) {
        n = _n;
        cle(bit, 0);
    }
    int lowb(int x) { return x & -x; }
    void add(int i, int x) {
        for(; i <= n; i += lowb(i))
            bit[i] += x;
    }
    int sum(int i) {
        int s = 0;
        for(; i; i -= lowb(i))
            s += bit[i];
        return s;
    }
} bt;
int main() {
#ifndef ONLINE_JUDGE
    freopen("E:1.in", "r", stdin);
#endif
    fread(Buf, 1, BUF, stdin);
    while(1) {
        read(n);
        if(n == 0) break;
        bt.ori(n);
        for(int i = 0; i < n; i++) {
            read(a); read(b);
            bt.add(a, 1);
            bt.add(b + 1, -1);
        }
        for(int i = 1; i <= n; i++) {
            write(bt.sum(i));
            if(i == n) writechar('\n');
            else writechar(' ');
        }
    }
    fwrite(Out, 1, ou - Out, stdout);
    return 0;
}

转载于:https://www.cnblogs.com/s1124yy/p/7189986.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值