[主席树]HDOJ3874 Necklace

题意:n个数 m个询问

询问的是[l, r]区间内不同的数的和

没有修改,静态的主席树即可

SPOJ QUERY 一样 将重复的元素建树即可

注意范围:$N \le  50000$ 每个值不超过1000000

也就是加起来会爆int 要用LL

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 typedef long long LL;
  4 #define lson l, m
  5 #define rson m+1, r
  6 const int N=5e4+5;
  7
  8 int L[N<<5], R[N<<5];
  9 LL sum[N<<5];
 10 int tot;
 11 int a[N], T[N];
 12 int read()
 13 {
 14     char ch=‘ ‘;
 15     int ans=0;
 16     while(ch<‘0‘ || ch>‘9‘)
 17         ch=getchar();
 18     while(ch<=‘9‘ && ch>=‘0‘)
 19     {
 20         ans=ans*10+ch-‘0‘;
 21         ch=getchar();
 22     }
 23     return ans;
 24 }
 25
 26 int build(int l, int r)
 27 {
 28     int rt=(++tot);
 29     sum[rt]=0;
 30     if(l<r)
 31     {
 32         int m=(l+r)>>1;
 33         L[rt]=build(lson);
 34         R[rt]=build(rson);
 35     }
 36     return rt;
 37 }
 38
 39 int update(int pre, int l, int r, int x, int val)
 40 {
 41     int rt=(++tot);
 42     L[rt]=L[pre], R[rt]=R[pre], sum[rt]=sum[pre]+val;
 43     if(l<r)
 44     {
 45         int m=(l+r)>>1;
 46         if(x<=m)
 47             L[rt]=update(L[pre], lson, x, val);
 48         else
 49             R[rt]=update(R[pre], rson, x, val);
 50     }
 51     return rt;
 52 }
 53
 54 LL query(int u, int v, int l, int r, int k)
 55 {
 56      if(l>=k)
 57         return sum[v]-sum[u];
 58     int m=(l+r)>>1;
 59     LL ans=0;
 60     if(m>=k)
 61         ans+=query(L[u], L[v], lson, k);
 62     ans+=query(R[u], R[v], rson, k);
 63     return ans;
 64 }
 65
 66 LL all[N];
 67 int main()
 68 {
 69     int t;
 70     scanf("%d", &t);
 71     while(t--)
 72     {
 73         tot=0;
 74         int n=read();
 75 //        scanf("%d", &n);
 76         all[0]=0;
 77         for(int i=1; i<=n; i++)
 78         {
 79 //            scanf("%d", &a[i]);
 80             a[i]=read();
 81             all[i]=all[i-1]+a[i];
 82         }
 83            T[0]=0;
 84         map<int, int> mp;
 85         mp.clear();
 86         for(int i=1; i<=n; i++)
 87         {
 88             if(mp.find(a[i])!=mp.end())
 89                 T[i]=update(T[i-1], 1, n, mp[a[i]], a[i]);
 90             else
 91                 T[i]=T[i-1];
 92             mp[a[i]]=i;
 93         }
 94         int m=read();
 95 //        scanf("%d", &m);
 96         while(m--)
 97         {
 98             int l, r;
 99             l=read(), r=read();
100 //            scanf("%d%d", &l, &r);
101             printf("%I64d\n", all[r]-all[l-1]-query(T[l-1], T[r], 1, n, l));
102         }
103     }
104     return 0;
105 }

HDOJ 3874

时间: 2024-10-13 00:15:30

[主席树]HDOJ3874 Necklace的相关文章

HDU3727--Jewel (主席树 静态区间第k大)

Jewel Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 985    Accepted Submission(s): 247 Problem Description Jimmy wants to make a special necklace for his girlfriend. He bought many beads with

HDU3727 Jewel(主席树+树状数组(或二分))

Problem Description Jimmy wants to make a special necklace for his girlfriend. He bought many beads with various sizes, and no two beads are with the same size. Jimmy can't remember all the details about the beads, for the necklace is so long. So he

[poj2104]可持久化线段树入门题(主席树)

解题关键:离线求区间第k小,主席树的经典裸题: 对主席树的理解:主席树维护的是一段序列中某个数字出现的次数,所以需要预先离散化,最好使用vector的erase和unique函数,很方便:如果求整段序列的第k小,我们会想到离散化二分和线段树的做法, 而主席树只是保存了序列的前缀和,排序之后,对序列的前缀分别做线段树,具有差分的性质,因此可以求任意区间的第k小,如果主席树维护索引,只需要求出某个数字在主席树中的位置,即为sort之后v中的索引:若要求第k大,建树时反向排序即可 1 #include

【BZOJ 3551】[ONTAK2010] Peaks加强版 Kruskal重构树+树上倍增+主席树

这题真刺激...... I.关于Kruskal重构树,我只能开门了,不过补充一下那玩意还是一棵满二叉树.(看一下内容之前请先进门坐一坐) II.原来只是用树上倍增求Lca,但其实树上倍增是一种方法,Lca只是他的一种应用,他可以搞各种树上问题,树上倍增一般都会用到f数组. |||.我们跑出来dfs序就能在他的上面进行主席树了. IV.别忘了离散. V.他可能不连通,我一开始想到了,但是我觉得出题人可能会是好(S)人(B),但是...... #include <cstdio> #include

[bzoj3932][CQOI2015]任务查询系统-题解[主席树][权值线段树]

Description 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的 任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si秒开始,在第Ei秒后结束(第Si秒和Ei秒任务也在运行 ),其优先级为Pi.同一时间可能有多个任务同时执行,它们的优先级可能相同,也可能不同.调度系统会经常向 查询系统询问,第Xi秒正在运行的任务中,优先级最小的Ki个任务(即将任务按照优先级从小到大排序后取前Ki个 )的优先级之和是多少.特别的,如

BZOJ_3207_花神的嘲讽计划1_(Hash+主席树)

描述 http://www.lydsy.com/JudgeOnline/problem.php?id=3207 给出一个长度为\(n\)的串,以及\(m\)个长度为\(k\)的串,求每个长度为\(k\)的串在原串\([x,y]\)区间是否出现过. 分析 这道题要求对比长度为\(k\)的串,于是我们把这些串的Hash值都算出来,问题就转化成了求\([x,y]\)的区间中是否出现过某Hash值. 求区间中某一个值出现了多少次,可以用主席树. p.s. 1.学习了主席树指针的写法,比数组慢好多啊...

[主席树]ZOJ3888 Twelves Monkeys

题意:有n年,其中m年可以乘时光机回到过去,q个询问 下面m行,x,y 表示可以在y年穿越回x年, 保证y>x 下面q个询问, 每个询问有个年份k 问的是k年前面 有多少年可以通过一种以上($\ge 2$)方法穿越回去的, 其中时光机只能用一次 比如案例 9 3 3 9 1 6 1 4 1 6 7 2 如图 对于询问 6这一年:1.穿越回第1年  2.等时间过呀过呀过到第9年,再穿越回第1年 那么第1年就有两种方法可以穿越回去, 同理, 2.3.4年也有同样两种方法(回到1再等时间过呀过 过到2

POJ2104主席树模板题

完成新成就——B站上看了算法https://www.bilibili.com/video/av4619406/?from=search&seid=17909472848554781180#page=2 K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 60158   Accepted: 21054 Case Time Limit: 2000MS Description You are working

【bzoj1146】[CTSC2008]网络管理Network 倍增LCA+dfs序+树状数组+主席树

题目描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条高速光缆组成.每个部门都有一个专属的路由器,部门局域网内的所有机器都联向这个路由器,然后再通过这个通信子网与其他部门进行通信联络.该网络结构保证网络中的任意两个路由器之间都存在一条直接或间接路径以进行通信. 高速光缆的数据传输速度非常快,以至于利用光缆传输的延迟时间可以忽略.但是由于路由器老化,在这些