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

    P1972 [SDOI2009]HH的项链

    经典区间数颜色问题。

    离线做法有树状数组和莫队,在线做法有主席树。

    莫队做法十分暴力,直接维护每个数当前的 cnt 再在单点更新的时候更新答案即可。

    树状数组做法:

    对于每一个位置维护一个前缀位置 (pre),那么询问就相当于是询问区间多少个位置的 (pre)(l) 之前。

    我们可以考虑离线下来然后差分,具体来说就是每次维护当前点为右端点,左端点为 1 时的值域树状数组,维护小于等于数 x 的 pre 有多少个,这个信息显然可以差分。

    然后主席树做法就是在线维护,每次直接在多树上询问即可。

    树状数组代码:

    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<iostream>
    using namespace std;
    struct node{
    	int l,r;
    	int before;
    	int ans;
    }q[1000005];
    int a[1000005],n,m,c[1000005],pre[1000005],used[1000005],p[1000005];
    inline int read(){int x=0,f=1;char ch=getchar();while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
    inline int lowbit(int x){return x&(-x);}
    inline bool cmp(node o,node p){return o.r<p.r;}
    inline void add(int x,int t){if(!x){return ;}while(x<=n){c[x]+=t;x+=lowbit(x);}return;}
    inline int query(int x){int ans=0;while(x){ans+=c[x];x-=lowbit(x);}return ans;}
    int main(){
    	n=read();
    	for(int i=1;i<=n;++i){a[i]=read();}
    	for(int i=1;i<=n;++i){
    		pre[i]=used[a[i]];
    		used[a[i]]=i;
    	}	
    	m=read();
    	for(int i=1;i<=m;++i){
    		q[i].l=read();
    		q[i].r=read();
    		q[i].before=i;
    	}
    	sort(q+1,q+m+1,cmp);
    	for(int i=1;i<=m;i++) p[q[i].before] = i;
    	int j=1;
    	for(int i=1;i<=m;++i){
    		while(j<=q[i].r){
    			add(j,1);
    			add(pre[j],-1);
    			j++;
    		
    		}
    		q[i].ans=query(q[i].r)-query(q[i].l-1);
    	}
    	
    	for(int i=1;i<=m;++i) printf("%d
    ",q[p[i]].ans);
    	return 0;
    }
    

    莫队

    #include<bits/stdc++.h>
    using namespace std;
    #define ri register int
    #define MAXN 1001000
    #define MAXA 1001000
    #define MAXQ 1001000
    #include <sys/mman.h>
    int a[MAXN],cnt[MAXA],bnum,q,n,belong[MAXA],siz,ans1[MAXQ];
    struct node{
        int l,r,id;
    }lin[MAXQ];
    
    struct _io {
        char* s;
        _io() : s((char*)mmap(0, 1 << 25, PROT_READ, MAP_PRIVATE, fileno(stdin), 0)) {}
        operator int() {
            int x = 0,w=0;
            while((*s)<'0') w|=(!((*s)^45)),++s;
            while((*s)>='0') x=(x<<3)+(x<<1)+((*s++)&15);
            return x*(w?-1:1);
        }
    } it;
    
    #define read() it
    template< typename T >inline void write(T x)
    {
        if(x>9) write(x/10);
        putchar(x%10^48);
    }
    inline bool cmp(node a,node b)
    {
        return (belong[a.l]^belong[b.l])?belong[a.l]<belong[b.l]:((belong[a.l]&1)?a.r<b.r:a.r>b.r);
    }
    
    int main()
    {
        n=read();
        siz=2135;
        bnum=ceil((double)n/siz);
        for(ri i=1;i<=n;++i)
        {
            belong[i]=i/siz;
        }
        for(ri i=1;i<=n;++i) a[i]=read();
        q=read();
        for(ri i=1;i<=q;++i)
        {
            lin[i].l=read(),lin[i].r=read();
            lin[i].id=i;
        }
        sort(lin+1,lin+1+q,cmp);
        int l=1,r=0,now=0;
        for(ri i=1;i<=q;++i)
        {
            int ql=lin[i].l,qr=lin[i].r;
            while(l<ql) now-=!--cnt[a[l++]];
            while(l>ql) now+=!cnt[a[--l]]++;
            while(r<qr) now+=!cnt[a[++r]]++;
            while(r>qr) now-=!--cnt[a[r--]];
            ans1[lin[i].id]=now;
        }
        for(ri i=1;i<=q;++i)
        {
            write(ans1[i]);
            putchar('
    ');
        }
    }
    
  • 相关阅读:
    【转载】动态加载wpf控件主题样式资源
    paip.批处理清理java项目冗余jar的方法
    paip.java OutOfMemoryError 解决方法o33
    paip.java win程序迁移linux的最佳实践
    paip.java c# .net php python调用c++ c dll so windows api 总结
    paip.提高效率微信 手机app快速开发平台—微网络撬动大市场
    paip.Log4j配置不起作用的解决
    paip.获取地理位置根据Ip
    paip.java 开发中web server的选择jboss resin tomcat比较..
    paip.提升安全性Des加密 java php python的实现总结
  • 原文地址:https://www.cnblogs.com/Akmaey/p/14686873.html
Copyright © 2011-2022 走看看