【BZOJ】2453: 维护队列【BZOJ】2120: 数颜色 二分+分块(暴力能A)

 先说正解:把所有相同的数相成一个链在每一个区间里的种数就是不同链的链头,那么记录每个数的上个相同数所在位置,那么只要找出l到r之间前驱值在l之前的数的个数就可以了


 本人打的暴力,有一个小技巧,用char代替int水题,用int里的值不同来去掉memset

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<cmath>
#include<iostream>
#define MAXN 10100
using namespace std;
char ex[103][103][11003];
map<int,int>mp;
int a[MAXN],pos[MAXN],t,len,n,m,sz,f[110][110],now[11100];
inline void pre(int x)
{
   int ans=0;
   for(int i=(x-1)*len+1;i<=n;i++)
   {
      if(ex[x][pos[i]][a[i]])
      {
         for(int j=pos[i];j<=t;j++)
          ex[x][j][a[i]]++;
         continue;
      }
      for(int j=pos[i];j<=t;j++)
      {
        ex[x][j][a[i]]=1;
        f[x][j]++;
      }
   }
}
inline void work1(int ohou)
{
   int l,r;
   scanf("%d%d",&l,&r);
   int z=pos[l],y=pos[r];
   int ans=0;
   if(pos[r]-pos[l]<=1)
   {
     for(int i=l;i<=r;i++)
     {
       if(now[a[i]]==ohou)continue;
       ans++;
       now[a[i]]=ohou;
     }
   }
   else
   {
     z++,y--;
     ans=f[z][y];
     int zzh=pos[l]*len;
     for(int i=l;i<=zzh;i++)
     {
       if(now[a[i]]==ohou||ex[z][y][a[i]])continue;
       now[a[i]]=ohou;
       ans++;
     }
     for(int i=(pos[r]-1)*len+1;i<=r;i++)
     {
       if(now[a[i]]==ohou||ex[z][y][a[i]])continue;
       now[a[i]]=ohou;
       ans++;
     }
   }
   printf("%d\n",ans);
}
inline void work2()
{
   int po,to;
   scanf("%d%d",&po,&to);
   if(mp[to]==0)
    mp[to]=++sz;
   to=mp[to];
   int x0=a[po];
   a[po]=to;
   int p1=pos[po];
   for(int i=p1;i>0;i--)
    for(int j=p1;j<=t;j++)
    {
      ex[i][j][x0]--;
      if(ex[i][j][x0]==0)f[i][j]--;
      ex[i][j][to]++;
      if(ex[i][j][to]==1)f[i][j]++;
    }
}
int main()
{
   scanf("%d%d",&n,&m);
   len=(int)sqrt(n+0.5);
   for(int i=1;i<=n;i++)
   {
     scanf("%d",&a[i]);
     if(mp[a[i]]==0)
       mp[a[i]]=++sz;
     a[i]=mp[a[i]];
     pos[i]=(i-1)/len+1;
   }
   t=pos[n];
   for(int i=1;i<=t;i++)
     pre(i);
   while(m--)
   {
     char s[2];
     scanf("%s",s);
     if(s[0]=='Q')work1(m);
     else work2();
   }
   return 0;
}

 

posted @ 2017-06-15 11:07  TS_Hugh  阅读(215)  评论(0编辑  收藏  举报