zoukankan      html  css  js  c++  java
  • 【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
    ",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;
    }
    苟利国家生死以, 岂因祸福避趋之。
  • 相关阅读:
    递归要记得返回
    git push的时候报Unable to find remote helper for 'https'的错误
    iphone手机上的click和touch事件
    对jquery的conflict方法的解读
    开发富文本编辑器的一些体会
    使用jquery制作动态加载型菜单
    解决jquery$命名符和其它框架的冲突问题
    基于geolocation来获取经纬度地址
    Python学习笔记2解析数据
    Python学习笔记1数据类型
  • 原文地址:https://www.cnblogs.com/TSHugh/p/7016427.html
Copyright © 2011-2022 走看看