Luogu4113 HEOI2012 采花 树状数组

传送门



发现这种重复只算一个的题目老是想不出来……

老套路,先对询问离线,按照右端点从小到大排序。然后我们考虑在右端点右移时新加入的那些位置的贡献,设$pre_i$表示与第$i$个位置相同数字的最后一个位置,那么将第$t$个数字放入的时候,$pre_t$就会产生$1$的贡献,而$pre_{pre_t}$的贡献因为$pre_t$的贡献而变成$0$,可以使用树状数组维护,每一次查询一段区间的贡献和即可。

 1 #include<bits/stdc++.h>
 2 //This code is written by Itst
 3 using namespace std;
 4
 5 inline int read(){
 6     int a = 0;
 7     bool f = 0;
 8     char c = getchar();
 9     while(c != EOF && !isdigit(c)){
10         if(c == ‘-‘)
11             f = 1;
12         c = getchar();
13     }
14     while(c != EOF && isdigit(c)){
15         a = (a << 3) + (a << 1) + (c ^ ‘0‘);
16         c = getchar();
17     }
18     return f ? -a : a;
19 }
20
21 const int MAXN = 2e6 + 7;
22 struct query{
23     int l , r , ind;
24 }que[MAXN];
25 int col[MAXN] , Tree[MAXN] , ans[MAXN] , last[MAXN][2] , N , c , Q;
26
27 bool operator <(query a , query b){
28     return a.r < b.r;
29 }
30
31 inline int lowbit(int x){
32     return x & -x;
33 }
34
35 inline void modify(int x , int add){
36     while(x <= N){
37         Tree[x] += add;
38         x += lowbit(x);
39     }
40 }
41
42 inline int get(int x){
43     int sum = 0;
44     while(x){
45         sum += Tree[x];
46         x -= lowbit(x);
47     }
48     return sum;
49 }
50
51 inline void add(int x){
52     if(!last[col[x]][0])
53         last[col[x]][0] = x;
54     else{
55         if(last[col[x]][1])
56             modify(last[col[x]][1] , -1);
57         last[col[x]][1] = last[col[x]][0];
58         last[col[x]][0] = x;
59         modify(last[col[x]][1] , 1);
60     }
61 }
62
63 int main(){
64 #ifndef ONLINE_JUDGE
65     freopen("4113.in" , "r" , stdin);
66     freopen("4113.out" , "w" , stdout);
67 #endif
68     N = read();
69     c = read();
70     Q = read();
71     for(int i = 1 ; i <= N ; ++i)
72         col[i] = read();
73     for(int i = 1 ; i <= Q ; ++i){
74         que[i].l = read();
75         que[i].r = read();
76         que[i].ind = i;
77     }
78     sort(que + 1 , que + Q + 1);
79     for(int i = 1 ; i <= Q ; ++i){
80         for(int j = que[i - 1].r + 1 ; j <= que[i].r ; ++j)
81             add(j);
82         ans[que[i].ind] = get(N) - get(que[i].l - 1);
83     }
84     for(int i = 1 ; i <= Q ; ++i)
85         printf("%d\n" , ans[i]);
86     return 0;
87 }

原文地址:https://www.cnblogs.com/Itst/p/10090573.html

时间: 2024-12-13 03:38:24

Luogu4113 HEOI2012 采花 树状数组的相关文章

[HEOI2012]采花 树状数组

题目描述 萧薰儿是古国的公主,平时的一大爱好是采花. 今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花. 花园足够大,容纳了n朵花,花有c种颜色(用整数1-c表示),且花是排成一排的,以便于公主采花.公主每次采花后会统计采到的花的颜色数,颜色数越多她会越高兴!同时,她有一癖好,她不允许最后自己采到的花中,某一颜色的花只有一朵.为此,公主每采一朵花,要么此前已采到此颜色的花,要么有相当正确的直觉告诉她,她必能再次采到此颜色的花. 由于时间关系,公主只能走过花园连续的一段进行采花,便让女仆

[bzoj2743][HEOI2012]采花(树状数组+离线)

2743: [HEOI2012]采花 Time Limit: 15 Sec  Memory Limit: 128 MBSubmit: 1832  Solved: 954[Submit][Status][Discuss] Description 萧芸斓是Z国的公主,平时的一大爱好是采花. 今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花.花园足够大,容纳了n朵花,花有c种颜色(用整数1-c表示),且花是排成一排的,以便于公主采花.公主每次采花后会统计采到的花的颜色数,颜色数越多她会越高兴

BZOJ 2743 HEOI2012 采花 树状数组

题目大意:给定一个序列,多次询问区间内出现两次以上的数的数量 n<=100W 莫队不用想了 考虑对于每个区间的左端点 对这个区间有贡献的数是从这个端点开始所有第二次出现的数 于是我们将区间按照左端点排序  然后从左向右扫 令next[i]为i位置上的数下一次出现的位置 初始将所有第二次出现的数加入树状数组 然后每删除一个点i 将next[i]从树状数组中删除 然后将next[next[i]]加入树状数组 然后处理区间就在树状数组上查询右端点即可 #include<cstdio> #inc

[BZOJ2743] [HEOI2012] 采花 (树状数组)

Description 萧芸斓是Z国的公主,平时的一大爱好是采花. 今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花.花园足够大,容纳了n朵花,花有c种颜色(用整数1-c表示),且花是排成一排的,以便于公主采花.公主每次采花后会统计采到的花的颜色数,颜色数越多她会越高兴!同时,她有一癖好,她不允许最后自己采到的花中,某一颜色的花只有一朵.为此,公主每采一朵花,要么此前已采到此颜色的花,要么有相当正确的直觉告诉她,她必能再次采到此颜色的花.由于时间关系,公主只能走过花园连续的一段进行采花

luogu4113 [HEOI2012]采花

https://www.luogu.org/problemnew/show/P4113 简化版题意:求出区间中有几个数出现了两次以上 题目要求出现两次以上,而且出现 10 次对答案只产生 1 的贡献,可以考虑对数字做一些变化 原数组:1 2 3 2 3 3 1 权值数组:0 0 0 1 1 0 1 对于在区间中出现第二次的数的权值为 1,其余为 0,这样只需要树状数组维护一下区间和就行了 将所有询问按照 l 排序,将 l 相同的做掉,不相同的可以在树状数组上修改,对于一个 l 如果不可能出现在询

BZOJ_2743_[HEOI2012]采花_离线+树状数组

Description 萧芸斓是Z国的公主,平时的一大爱好是采花.今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花 .花园足够大,容纳了n朵花,花有c种颜色(用整数1-c表示),且花是排成一排的,以便于公主采花.公主每次 采花后会统计采到的花的颜色数,颜色数越多她会越高兴!同时,她有一癖好,她不允许最后自己采到的花中,某 一颜色的花只有一朵.为此,公主每采一朵花,要么此前已采到此颜色的花,要么有相当正确的直觉告诉她,她必 能再次采到此颜色的花.由于时间关系,公主只能走过花园连续的一段进

bzoj2743: [HEOI2012]采花--离线树状数组+差分

题目大意:给定一个区间,查询子区间里出现次数不小于二的数的个数 此题想了好久没想出来,后来是在网上学习的一个方法 首先按查询区间的右端点进行排序,按右端点从小到大处理 假设pre[a[i]]是与a[i]相同的前一个数的位置,记为left[i] 当查询到第i个数时,对left[left[i]]+1~left[i]的每个数的权值w[]加1 也就是说:左端点在left[left[i]]+1~left[i]内,右端点为i的区间里,出现次数不小于二的数+1 那么对于查询i,答案就是w[left[i]] 因

HYSBZ 4551 (树状数组) 采花

题目:这里 题意: 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为1),有以下 两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均无标记,而且对于某个 结点,可以打多次标记.)2. 询问操作:询问某个结点最近的一个打了标记的祖先(这个结点本身也算自己的祖 先)你能帮帮他吗? Input 输入第一行两个正整数N和Q分别表示节点个数和操作次数接下来N-1行,每行两个正整数u,v(1≤u,v≤n)表示u到v 有一条有向边接

BZOJ2743: [HEOI2012]采花

2743: [HEOI2012]采花 Time Limit: 15 Sec  Memory Limit: 128 MBSubmit: 2386  Solved: 1231[Submit][Status][Discuss] Description 萧芸斓是Z国的公主,平时的一大爱好是采花. 今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花.花园足够大,容纳了n朵花,花有c种颜色(用整数1-c表示),且花是排成一排的,以便于公主采花.公主每次采花后会统计采到的花的颜色数,颜色数越多她会越高