zoukankan      html  css  js  c++  java
  • [SDOI2009]HH的项链

    ## [ 传送门 ](https://www.luogu.org/problemnew/show/P1972)

    Solution

    这是一道很经典的题目吖

    莫队的话,在洛谷上吸吸氧就能过了

    其实这题是由很多做法的吧

    我们一种颜色显然只有在它第一次出现的时候有贡献

    或者说,我们让它在最后一次出现的时候有贡献

    然后把按照r从小到大排序,用树状数组维护每个点最后一次出现的位置(权值为1,之前的为0)

    然后区间求和就行啦

    主席树也能做?

    这下我们让每个数第一次出现有贡献~

    对于每个位置,记下该数上次出现的位置,如果小于l,那么它是第一次出现的

    维护一个last的权值线段树,然后每次查询区间中小于l的数


    Code 

    
    #include<bits/stdc++.h>
    #define ll long long
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    inline int read()
    {
    	int x=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    	return x*f;
    }
    #define MN 500005
    int col[MN],l,r,pos[MN];
    struct ques{
    	int l,r,id;
    	bool operator<(const ques&x) const{return pos[l]^pos[x.l]?pos[l]<pos[x.l]:r<x.r;}
    }q[MN];
    int num[MN<<1],ans,print[MN];
    int main()
    {
    	register int n,m,i,T;
    	n=read();
    //	T=(int)(sqrt(n));
    	T=1500;
    	for(i=1;i<=n;++i) col[i]=read(),pos[i]=(i+1)/T+1;
    	m=read();
    	for(i=1;i<=m;++i) q[i].l=read(),q[i].r=read(),q[i].id=i;
    	std::sort(q+1,q+m+1);
    	register int L,R;
    	for(L=1,R=0,i=1;i<=m;++i)
    	{
    		for(;R<q[i].r;++R) ans+=(!num[col[R+1]]),num[col[R+1]]++;
    		for(;R>q[i].r;--R) ans-=(num[col[R]]==1),num[col[R]]--;
    		for(;L>q[i].l;--L) ans+=(!num[col[L-1]]),num[col[L-1]]++;
    		for(;L<q[i].l;++L) ans-=(num[col[L]]==1),num[col[L]]--;
    		print[q[i].id]=ans; 
    	}
    	for(i=1;i<=m;++i) printf("%d
    ",print[i]);
    }
    
    


    Blog来自PaperCloud,未经允许,请勿转载,TKS!

  • 相关阅读:
    div居中鼠标悬浮显示下拉列表
    javascript循环
    javascript函数
    javascript时间、随机数
    javascript外部使用
    Javascript 探路
    CSS六大选择器(注释css表里不能加注释!!)
    框架链接
    Jmeter分布式测试dubbo接口2
    Jmeter分布式测试dubbo接口1
  • 原文地址:https://www.cnblogs.com/PaperCloud/p/10166288.html
Copyright © 2011-2022 走看看