首页 > 其他分享 >题解 [SDOI2009] HH的项链

题解 [SDOI2009] HH的项链

时间:2023-07-25 11:47:00浏览次数:51  
标签:题解 LL long HH 端点 权值 区间 SDOI2009 放权

题目链接

对于这类问区间不同数的总数,显然是不能用线段树直接维护的,毕竟不符合区间区间可加性。

考虑对于一个右端点固定的询问,哪些数字实际上是有权值的。

比如区间 1 3 3 2 3 1 2,显然,实际上对于相同的数字,只有一个是有权值的,其他权值均为 \(0\)。但是这样还是无法起到简化的作用,毕竟对于 3 3 3,要选那个 \(3\) 放权值呢?

由于我们固定右端点,所以取最右边的放权值一定可以囊括所有情况。对于上面的例子,我们应该这样放权值:

0 0 0 1 0 1 1
1 3 3 3 1 1 2

答案即为一个区间内的权值之和。

考虑如何实现上述的“固定右端点”,我们可以按照右端点从小到大排序,对其进行离线,对于新加入的右端点(颜色记作 \(col\)),若前面有与 \(col\) 相同的,将那个点的权值减一,这要求先预处理出每个点前面与其颜色相同的点的坐标,并使用树状数组进行单点修改区间查询。

点击查看代码
#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
LL read() {
    LL sum=0,flag=1; char c=getchar();
    while(c<'0'||c>'9') {if(c=='-') flag=-1; c=getchar();}
    while(c>='0'&&c<='9') {sum=sum*10+c-'0'; c=getchar();}
    return sum*flag;
}

const int N=1e6+10;
int n,m;
int a[N],p[N],lst[N];
int ans[N],tr[N];
struct node {
    int l,r,id;
}q[N];

int cmp(node x,node y) {
    return x.r<y.r;
}

int lowbit(int x) {
    return x&(-x);
}

void add(int nd,int x) {
    for(int i=nd;i<=n;i+=lowbit(i)) tr[i]+=x;
}

int query(int nd) {
    int sum=0;
    for(int i=nd;i;i-=lowbit(i)) sum+=tr[i];
    return sum;
}

int main() {
    // freopen("a.in","r",stdin);
    // freopen("a.out","w",stdout);

    n=read();
    for(int i=1;i<=n;i++) {
        a[i]=read();
        lst[i]=p[a[i]];
        p[a[i]]=i;
    }

    cin>>m;
    for(int i=1;i<=m;i++) {
        q[i].l=read(); q[i].r=read();
        q[i].id=i;
    }
    sort(q+1,q+1+m,cmp);
    int j=0;
    for(int i=1;i<=m;i++) {
        while(j+1<=q[i].r) {
            j++;
            add(j,1);
            if(lst[j]) add(lst[j],-1);
        }
        ans[q[i].id]=query(q[i].r)-query(q[i].l-1);
    }
    for(int i=1;i<=m;i++) cout<<ans[i]<<'\n';


    return 0;
}

标签:题解,LL,long,HH,端点,权值,区间,SDOI2009,放权
From: https://www.cnblogs.com/zhangyuzhe/p/17579405.html

相关文章

  • 题解 链表 (chain)
    题目链接首先考虑没有修改怎么做。两种做法。想到询问的形式为保留\(\gek\)的连通块个数,那么先将全部数字按照权值排序,然后从后往前做一遍并查集,并同时统计连通块的数量,在询问时只需二分找到第一个\(\gek\)的位置,将这个位置的答案输出即可。注意考虑答案为\(0\)的情况......
  • 【大联盟】20230713 T1 方向矩阵(rect) 题解 CF1666A 【Admissible Map】
    题目描述here。题解赛时得分:60/100。想到了正解,但调不出来,就改写暴力了。。。首先,我们把问题转化成每个点都入度为\(1\)。我们考虑合法子串只有两种形式:注意到U和D,要么同时出现,要么同时不出现,因为如果存在U,就说明U所在这一行得到度数减少了,一定需要上一行D来弥补......
  • luogu P3203 [HNOI2010] 弹飞绵羊 题解
    题目传送门:P3203[HNOI2010]弹飞绵羊题意\(n\)个数,满足\(i<a_i≤N+1\),\(m\)次下面两种操作修改一个数\(a_i\)从\(x\)开始跳,\(x=a_x\),几次能够跳出序列\(n\leq2*10^5,m<10^5\)分析数据范围比较大,单纯搜索模拟肯定会T,那么考虑每次让他跳一段就......
  • 题解 P7971【[KSN2021] Colouring Balls】
    postedon2022-10-0819:07:28|under题解|sourceproblem交互库有一个长为\(n\)的颜色序列,你可以询问区间\([l,r]\)中有多少种颜色,最后还原交互库手中的序列,只需要保持相对顺序不变。\(n\leq10^3\),最多询问次数\(Q=2000\)或\(Q=10^4\)。solution令\(C\)为\([1......
  • CF1051G Distinctification题解
    link首先可以发现,题目给定的两种操作为我们提供了“反悔机制”,所以有:结论\(1\):即任何一个可以到达的局面都能到达最优解。利用这个结论,首先我们先去重。继续提炼性质,与相差不到\(1\)的数为基准\(+1\)与\(-1\)操作,将这个数的变化范围限制在了一个区间,并且这个区间的数能......
  • 题解 Codeforces Round 887 (Div 1+Div 2) / CF1853AB,CF1852ABCD
    下大分!悲!Div1只过了1A!!!但还是补完整场Div2吧。A.Desortinghttps://codeforces.com/problemset/problem/1853/Aproblem用操作:\([1,i]++,[i+1,n]--\),使得数组不单调不降,求最小操作次数。\(n\leq10^5\)。solution操作等同于在差分数组上选出\(i\),做\(c_1:=c_1+1,c_i:......
  • UOJ #284. 快乐游戏鸡题解(长链剖分+单调栈合并)
    UOJ#284.快乐游戏鸡题解(长链剖分+单调栈合并)题面一番战斗之后,程序猿被计算鸡们赶走了。随着垫子计算鸡一声令下:“追!”,于是计算鸡村全村上下开始乘胜追击。计算鸡们希望在新的一年到来之际给程序猿以重创,出掉这一年的恶气。可是程序猿一追就走,一走就跑,一跑就无影无踪。计算鸡......
  • 洛谷CF1738C题解
    好一道博弈论水题题目传送门更好的食用体验题目大意:给定长度为$n$的数列$a_1,a_2,\dots,a_n$,两名玩家Alice、Bob依次以最优策略从数列中取走一个数,Alice先取,直至为空博弈结束。若Alice取走的所有数之和为偶,Alice胜利;若Alice取走的所有数之和为奇,Bob胜利......
  • 【题解】Imbalanced Arrays - Codeforces 1852B
    出处:CodeforcesRound887链接:https://codeforces.com/problemset/problem/1852/B题目大意:给定一个包含\(n\)个非负整数的频次序列\(f\)。构造任意一个等长的整数序列\(b\),要求①\(b\in[-n,n]\)but$b\neq0$②\(b\)中不存在相反数③对于每个坐标\(i\)......
  • 【P8302 题解】
    Solution设\(g(x)\)表示\(x\)的最小质因子。则\(f(x)=n+\dfrac{n}{g(x)}=\dfrac{g(x)+1}{g(x)}\timesn\)。分情况讨论:\(g(x)=2\),经过\(1\)次变换之后,\(f(x)\)增加了一个因子\(3\),减少了一个因子\(2\)。\(g(x)>2\),则满足\(g(x)\nmid2\),否则与最小质因子矛盾,......