zoukankan      html  css  js  c++  java
  • 【洛谷 P2464】[SDOI2008]郁闷的小J(线段树)

    题目链接
    这题我很久之前用分块写过,没写出来。。
    今天又看到了,于是下决心把这题做出来。
    这次我用线段树写的,直接对每本书的编号Hash一下然后离散化然后各建一棵线段树,维护当前编号在某个位置有没有书,就行了。
    为了卡空间,我用了(vector),同时指针建树,结构体里不保存当前节点维护的区间,区间作为参数递归,这样就能过了,空间复杂度应该是(O(N+M log N))
    另外Hash的边界搞大一点,第一次只弄了10W 80分,改成100W就A了。

    #include <iostream>
    #include <cstdio>
    #include <vector>
    #define re register
    using namespace std;
    inline int read(){
        int s = 0, w = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9') { if(ch == '-') w = -1; ch = getchar(); }
        while(ch >= '0' && ch <= '9') { s = s * 10 + ch - '0'; ch = getchar(); }
        return s * w;
    }
    const int MAXN = 100010;
    int num; 
    struct Seg_Tree{
        int sum;
        Seg_Tree *l, *r;
        Seg_Tree() { l = NULL; r = NULL; sum = 0; }
        void pushup(){
            sum = 0;
            if(l != NULL) sum += l->sum;
            if(r != NULL) sum += r->sum;
        }
        void Add(int c, int p, int L, int R){
            if(L == R){
              sum += c;
              return;
            }
            int mid = (L + R) >> 1;
            if(p > mid){
              if(r == NULL)
                r = new Seg_Tree;
              r->Add(c, p, mid + 1, R);
            }
            else{
              if(l == NULL)
                l = new Seg_Tree;
              l->Add(c, p, L, mid); 
            }
            pushup();
        }
        int Ask(int L, int R, int wl, int wr){
           int ans = 0;
           if(L >= wl && R <= wr) return sum;
           if(L > wr || R < wl) return 0;
           int mid = (L + R) >> 1;
           if(l != NULL) ans += l->Ask(L, mid, wl, wr);
           if(r != NULL) ans += r->Ask(mid + 1, R, wl, wr);
           return ans;
        }
    };
    vector <Seg_Tree> tree;
    int n, m, v[MAXN * 10], id[MAXN * 10];
    int getHash(int x){
        int hash = x % 1000000;
        if(!v[hash]) v[hash] = x;
        else while(v[hash] != x && v[hash]) hash = (hash + 233) % 10000;
        return hash;
    }
    int a, b, c;
    int w[MAXN];
    char ch;
    int main(){
        tree.push_back(Seg_Tree());
        n = read(); m = read();
        for(re int i = 1; i <= n; ++i){
           w[i] = read();
           re int hash = getHash(w[i]);
           if(!id[hash]) id[hash] = ++num, tree.push_back(Seg_Tree());
           tree[id[hash]].Add(1, i, 1, n);
        }
        for(re int i = 1; i <= m; ++i){
           do{
             ch = getchar();
           }while(ch != 'C' && ch != 'Q');
           if(ch == 'C'){
             a = read(); b = read();
             re int hash = getHash(w[a]);
             tree[id[hash]].Add(-1, a, 1, n);
             hash = getHash(b);
             if(!id[hash]) id[hash] = ++num, tree.push_back(Seg_Tree());
             tree[id[hash]].Add(1, a, 1, n);
             w[a] = b;
           }
           else{
             a = read(); b = read(); c = read();
             re int hash = getHash(c);
             if(!id[hash]) id[hash] = ++num, tree.push_back(Seg_Tree());
             printf("%d
    ", tree[id[hash]].Ask(1, n, a, b));
           }
        }
        return 0;
    }
    
    
  • 相关阅读:
    socket实现一个简单的echo服务
    Netty实现丢弃服务协议(Netty4.X学习一)
    大型情感剧集Selenium:8_selenium网页截图的四种方法
    python原类、类的创建过程与方法
    Flask使用bootstrap为HttpServer添加上传文件功能
    充满含金量的一场云原生Meetup,入场券免费发送中……
    Hadoop伪分布式集群的安装部署
    从缓冲池命中率角度判断自己的MYSQL数据库是否需要扩容内存
    MySQL分区表概述
    如何防止mysql数据库被勒索
  • 原文地址:https://www.cnblogs.com/Qihoo360/p/9522391.html
Copyright © 2011-2022 走看看