• 【莫队算法】URAL


    http://www.cnblogs.com/icode-girl/p/5783983.html

    要注意卡片没有都被使用的情况。

    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    #define N 100010
    int K,n,a[N],nex[N],now[N],m,anss[N];
    bool vis[N];
    struct ASK{int l,r,p;}Q[N];
    int num[N];
    bool operator < (const ASK &a,const ASK &b)
    {return num[a.l]!=num[b.l] ? num[a.l]<num[b.l] : a.r<b.r;}
    void makeblock()
    {
        int sz=sqrt(n),sum=1; if(!sz) sz=1;
        for(;sum*sz<n;++sum)
          {
            int r=sum*sz;
            for(int i=sz*(sum-1)+1;i<=r;++i)
    		  num[i]=sum;
          }
        for(int i=sz*(sum-1)+1;i<=n;++i)
    	  num[i]=sum;
    }
    int T[N],ans;
    void Insert(int x)
    {
    	if(!T[x]) ++ans;
    	++T[x];
    }
    void Delete(int x)
    {
    	--T[x];
    	if(!T[x]) --ans;
    }
    int main()
    {
    	//freopen("c.in","r",stdin);
    	scanf("%d%d",&K,&n);
    	for(int i=1;i<=n;++i)
    	  scanf("%d",&a[i]);
    	int k=0;
    	for(int i=1;i<=n;++i)
    	  if(!vis[a[i]])
    	    {
    	      ++k;
    	      vis[a[i]]=1;
    	      printf("%d%c",a[i],k==K ? '
    ' : ' ');
    	    }
    	for(int i=1;i<=K;++i)
    	  if(!vis[i])
    	    {
    	      ++k;
    	      printf("%d%c",i,k==K ? '
    ' : ' ');
    	    }
    	for(int i=n;i>=1;--i)
    	  {
    	  	nex[i]=now[a[i]];
    	  	now[a[i]]=i;
    	  }
    	for(int i=1;i<=n;++i)
    	  if(nex[i]>i+1)
    	    {
    	      Q[++m].l=i+1;
    	      Q[m].r=nex[i]-1;
    	      Q[m].p=i;
    	    }
    	  else if(nex[i]==i+1)
    	    anss[i]=0;
    	  else
    	    anss[i]=K-1;
    	makeblock();
    	sort(Q+1,Q+m+1);
    	for(int i=Q[1].l;i<=Q[1].r;++i) Insert(a[i]);
        anss[Q[1].p]=ans;
        for(int i=2;i<=m;++i)
          {
            if(Q[i].l<Q[i-1].l){for(int j=Q[i-1].l-1;j>=Q[i].l;--j)Insert(a[j]);}
            else{for(int j=Q[i-1].l;j<Q[i].l;++j)Delete(a[j]);}
            if(Q[i].r<Q[i-1].r){for(int j=Q[i-1].r;j>Q[i].r;--j)Delete(a[j]);}
            else{for(int j=Q[i-1].r+1;j<=Q[i].r;++j)Insert(a[j]);}
            anss[Q[i].p]=ans;
          }
    	for(int i=1;i<=n;++i)
    	  printf("%d
    ",anss[i]);
    	return 0;
    }
  • 相关阅读:
    【PAT】1001 害死人不偿命的(3n+1)猜想(动态更新)
    文件指令集
    近距离接触电脑
    文件管理
    文件写作方法
    文件读取方法
    打开文件的逻辑
    话术库
    max的逻辑
    抽象化指令
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/6375208.html
Copyright © 2020-2023  润新知