hdu 3874 树状数组+离线处理

题意:

这和hdu 3333 根本就是一道题   链接:http://blog.csdn.net/u013382399/article/details/45689977

思路:

同hdu 3333

code:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<string>
#include<queue>
#include<map>
#include<set>
#include<cmath>
#include<cstdlib>
using namespace std;

#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define mem(a, b) memset(a, b, sizeof(a))
#define mod 1000000007
typedef pair<int,int> pii;
typedef long long LL;
//------------------------------
const int maxn = 50005;
const int maxq = 200005;

struct node{
    int s, e, id;
    bool operator < (const node nt) const{
        if(e != nt.e)
            return e < nt.e;
        else return s < nt.s;
    }
}qujian[maxq];
int n,q;
LL a[maxn];
LL ans[maxq];

struct BIT
{
    long long C[maxn];
    void init()
    {
        memset(C, 0, sizeof(C));
    }
    int lowbit(int x)
    {
        return -x&x;
    }
    long long get_Sum(int x)
    {
        long long ret = 0;
        while(x > 0)
        {
            ret += C[x];
            x -= lowbit(x);
        }
        return ret;
    }
    void add(int x,long long v)
    {
        while(x <= n)
        {
            C[x] += v;
            x += lowbit(x);
        }
    }
}bit;

void init(){
    scanf("%d",&n);
    for(int i = 1; i <= n; i++){
        scanf("%I64d",&a[i]);
    }
    scanf("%d",&q);
    int st, ed;
    for(int i = 0; i < q; i++){
        scanf("%d%d",&st, &ed);
        qujian[i].s = st;
        qujian[i].e = ed;
        qujian[i].id = i;
    }
}
map<long long, int> ma;
void solve(){
    sort(qujian, qujian+q);

//    for(int i = 0; i < q; i++){
//        printf("==%d %d==\n",qujian[i].s, qujian[i].e);
//
//    }

    ma.clear();
    bit.init();
    int start_ = 1;
    for(int i = 0; i < q; i++){
        for(int j = start_; j <= qujian[i].e; j++){
            if(ma.count(a[j])){
                bit.add(ma[a[j]],-a[j]);
            }
            bit.add(j,a[j]);
            ma[a[j]] = j;
        }
        ans[qujian[i].id] = bit.get_Sum(qujian[i].e) - bit.get_Sum(qujian[i].s-1);
        start_ = qujian[i].e + 1;
    }
    for(int i = 0; i < q; i++){
        printf("%I64d\n",ans[i]);
    }
}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        init();
        solve();
    }
    return 0;
}

用cin cout 会超时

时间: 2024-10-08 04:31:44

hdu 3874 树状数组+离线处理的相关文章

hdu 3333 树状数组+离线处理

http://acm.hdu.edu.cn/showproblem.php?pid=3333 不错的题,想了很久不知道怎么处理,而且答案没看懂,然后找个例子模拟下别人的代码马上懂了---以后看不懂的话就拿个例子模拟下别人的代码 举个例子:1 3 3 5 3 5 查询 a, 2 4 b, 2 5 最初是这么想的:对于a查询,倘若把第二个数第三个数变成1个3,那么到b查询,又出现了两个3,再做处理似乎还是O(n),而且如果先出现2,5查询,后出现2,4查询,那么还需要把删除的数补回来.....o(╯

hdu 4368 树状数组 离线维护

http://acm.hdu.edu.cn/showproblem.php?pid=4638 Problem Description There are n men ,every man has an ID(1..n).their ID is unique. Whose ID is i and i-1 are friends, Whose ID is i and i+1 are friends. These n men stand in line. Now we select an interv

Necklace HDU - 3874 (线段树/树状数组 + 离线处理)

Necklace HDU - 3874 Mery has a beautiful necklace. The necklace is made up of N magic balls. Each ball has a beautiful value. The balls with the same beautiful value look the same, so if two or more balls have the same beautiful value, we just count

HDU 3333 Turing Tree 树状数组 离线查询

题意: 给你一个数列,然后有n个查询,问你给定区间中不同数字的和是多少. 思路还是比较难想的,起码对于蒟蒻我来说. 将区间按照先右端点,后左端点从小到大排序之后,对于每个查询,我只要维护每个数字出现的最后一次就可以了(这个结论稍微想一下就可以证明是正确的). 然后就是简单的点更新,区间求和问题了- #include <cstdio> #include <cstring> #include <iostream> #include <map> #include

HDU 4417 Super Mario ( 超级马里奥 + 主席树 + 线段树/树状数组离线处理 + 划分树 )

HDU 4417 - Super Mario ( 主席树 + 线段树/树状数组离线处理 + 划分树 ) 这道题有很多种做法,我先学习的是主席树.后面陆续补上线段树离线和划分树 题目大意就是给定一个区间给定一个数列,每次要求你查询区间[L,R]内不超过K的数的数量 主席树做法: 最基本的是静态第k大,这里是求静态的 <= K,差不多,在Query操作里面需要修改修改 先建立size棵主席树,然后询问的时候统计的是 第R棵主席树中[1,K]的数量 - 第L-1棵主席树中[1,K]的数量 注意这里下标

HDU 3333 Turing Tree(树状数组离线处理)

HDU 3333 Turing Tree 题目链接 题意:给定一个数组,每次询问一个区间,求出这个区间不同数字的和 思路:树状数组离线处理,把询问按右端点判序,然后用一个map记录下每个数字最右出现的位置,因为一个数字在最右边出现,左边那些数字等于没用了,利用树状数组进行单点修改区间查询即可 代码: #include <cstdio> #include <cstring> #include <algorithm> #include <map> using n

Hdu 3887树状数组+模拟栈

题目链接 Counting Offspring Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1757    Accepted Submission(s): 582 Problem Description You are given a tree, it’s root is p, and the node is numbered fr

13杭州区域赛现场赛Rabbit Kingdom(树状数组+离线)

题意:给你一个长度数列,再给你m个询问(一个区间),问你在这个区间里面有多少个数与其他的数都互质. 解题思路:你看这种类型的题目都可以肯定这是 离线+树状数组(线段树).主要就是他的更新信息.这里我的处理是先把1-200000(每个数的范围)数里面所有的质因子求出来.然后从后往前遍历数组.会出现以下几种情况 1.a[k]的质因子在后面出现过而[更新标记] 和[被更新标记] 都为假 2.a[k]的质因子在后面出现过的那个位置 I   [更新标记]为 真 . 3.a[k]的质因子在后面出现过且那个位

HDU 1754 树状数组 解法

mnesia在频繁操作数据的过程可能会报错:** WARNING ** Mnesia is overloaded: {dump_log, write_threshold},可以看出,mnesia应该是过载了.这个警告在mnesia dump操作会发生这个问题,表类型为disc_only_copies .disc_copies都可能会发生. 如何重现这个问题,例子的场景是多个进程同时在不断地mnesia:dirty_write/2 mnesia过载分析 1.抛出警告是在mnesia 增加dump