zoukankan      html  css  js  c++  java
  • 解题报告: luogu P1972

    题目链接:P1972 [SDOI2009]HH的项链

    我们首先想到莫队,然后就被卡了。

    然后我就不会了。

    正解:

    对区间内每一个元素最后出现的位置作为有效位置,其他的都是无效位置。
    这样我们可以差分了!

    我们只需要维护一下每个位置是否是一种颜色的有效位置,对于这个区间内没有的位置,一定是前面有或者是还没出现过,这样的答案是正确的。可以用树状数组维护单点加与前缀和。

    最后,按 (r) 升序询问就好了。

    (Code:)

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    
    #define MAXN 1000005
    
    int n,m,col[MAXN],pos[MAXN];
    int l[MAXN],r[MAXN],lst=0,vis[MAXN]={0},ans[MAXN];
    
    inline int read()
    {
    	int x=0,w=1;
    	char c=getchar();
    	while(c<'0'||c>'9'){if(c=='-') w=-1;c=getchar();}
    	while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c-'0');c=getchar();};
    	return x*w;
    }
    
    struct tree
    {
    	int t[MAXN];
    	int lowbit(int x){return x&(-x);}
    	void add(int x,int y){for(int i=x;i<=n;i+=lowbit(i)) t[i]+=y;}
    	int query(int x){int ans=0;for(int i=x;i;i-=lowbit(i)) ans+=t[i];return ans;}
    }T;
    
    struct node
    {
    	int l,r,id;
    }a[MAXN];
    
    bool cmp(node n,node m){return n.r<m.r;}
    
    int main()
    {
    	n=read();
    	for(int i=1;i<=n;i++) col[i]=read();
    	m=read();
    	for(int i=1;i<=m;i++) a[i].l=read(),a[i].r=read(),a[i].id=i,vis[a[i].r]++;
    	sort(a+1,a+m+1,cmp);
    	memset(pos,0,sizeof(pos));
    	for(int i=1;i<=n;i++)
    	{
    		if(pos[col[i]]) T.add(pos[col[i]],-1);
    		T.add(i,1),pos[col[i]]=i;
    		for(int j=1;j<=vis[i];j++) lst++,ans[a[lst].id]=T.query(a[lst].r)-T.query(a[lst].l-1);
    	}
    	for(int i=1;i<=m;i++) printf("%d
    ",ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    Dom对象,控制html元素
    运算符总结
    数组
    变量命名规则
    css实现气泡说明框
    深入理解CSS中的层叠上下文和层叠顺序
    jquery书写
    二级导航
    iis配置
    Android ListView无法触发ItemClick事件
  • 原文地址:https://www.cnblogs.com/tlx-blog/p/13126755.html
Copyright © 2011-2022 走看看