loj#6284. 数列分块入门 8

#6284. 数列分块入门 8

题目:传送门 

简要题意:

   给出一个长为 n 的数列,以及 n 个操作,操作涉及区间询问等于一个数 c 的元素,并将这个区间的所有元素改为 c。

 


 

 

题解:

   超级超级超级恶心!!!

   码农就算了...lazy的运用搞得我几乎要吐:

   lazy就看看该块是不是同一数字嘛...不是的话就为-1,是的话就更新成该块的数字

   然后又到暴力表演了,不停分情况(其实也就三种左右),头尾+中间   

 


 

 

代码:

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<cstdlib>
  4 #include<cmath>
  5 #include<algorithm>
  6 #define mod 10007
  7 #define qread(x) x=read()
  8 using namespace std;
  9 typedef long long LL;
 10 inline LL read()
 11 {
 12     LL x=0,f=1;char ch;
 13     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 14     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
 15     return f*x;
 16 }
 17 LL n,a[110000],ba[110000];
 18 LL block,pos[110000];
 19 void sol(LL l,LL r,LL c)
 20 {
 21     LL ans=0;
 22     if(pos[l]==pos[r])
 23     {
 24         if(ba[pos[l]]==c)printf("%lld\n",r-l+1);
 25         else
 26         {
 27             if(ba[pos[l]]!=-1)
 28                 for(int i=(pos[l]-1)*block+1;i<=pos[l]*block;i++)
 29                     a[i]=ba[pos[l]];
 30             for(int i=l;i<=r;i++){if(a[i]==c)ans++;a[i]=c;}
 31             bool bk=false;
 32             for(int i=(pos[l]-1)*block+1;i<=pos[l]*block;i++)
 33                 if(a[i]!=c){bk=true;break;}
 34             if(bk==false)ba[pos[l]]=c;
 35             else ba[pos[l]]=-1;
 36             printf("%lld\n",ans);
 37         }
 38     }
 39     else
 40     {
 41         for(int i=pos[l]+1;i<=pos[r]-1;i++)
 42         {
 43             if(ba[i]==c)ans+=(i*block-((i-1)*block+1)+1);
 44             else if(ba[i]!=-1)ba[i]=c;
 45             else
 46             {
 47                 for(int j=(i-1)*block+1;j<=i*block;j++)
 48                 {
 49                     if(a[j]==c)ans++;
 50                     a[j]=c;
 51                 }
 52                 ba[i]=c;
 53             }
 54             continue;
 55         }
 56         if(ba[pos[l]]==c)ans+=(pos[l]*block-l+1);
 57         else 
 58         {
 59             if(ba[pos[l]]!=-1)
 60                 for(int i=(pos[l]-1)*block+1;i<=pos[l]*block;i++)
 61                     a[i]=ba[pos[l]];
 62             for(int i=l;i<=pos[l]*block;i++)
 63             {
 64                 if(a[i]==c)ans++;
 65                 a[i]=c;
 66             }
 67             bool bk=false;
 68             for(int i=(pos[l]-1)*block+1;i<=pos[l]*block;i++)
 69                 if(a[i]!=c){bk=true;break;}
 70             if(bk==false)ba[pos[l]]=c;
 71             else ba[pos[l]]=-1;
 72         }
 73         if(ba[pos[r]]==c)ans+=(r-((pos[r]-1)*block+1)+1);
 74         else 
 75         {
 76             if(ba[pos[r]]!=-1)
 77                 for(int i=(pos[r]-1)*block+1;i<=pos[r]*block;i++)
 78                     a[i]=ba[pos[r]];
 79             for(int i=(pos[r]-1)*block+1;i<=r;i++)
 80             {
 81                 if(a[i]==c)ans++;
 82                 a[i]=c;
 83             }
 84             bool bk=false;
 85             for(int i=(pos[r]-1)*block+1;i<=pos[r]*block;i++)
 86                 if(a[i]!=c){bk=true;break;}
 87             if(bk==false)ba[pos[r]]=c;
 88             else ba[pos[r]]=-1;
 89         }
 90         printf("%lld\n",ans);
 91     }
 92 }
 93 int main()
 94 {
 95     qread(n);for(int i=1;i<=n;i++)qread(a[i]);
 96     block=sqrt(n);
 97     for(int i=1;i<=n;i++)
 98     {    
 99         pos[i]=(i-1)/block+1;
100     }
101     memset(ba,-1,sizeof(ba));
102     for(int i=1;i<=n;i++)
103     {
104         LL l,r,c;qread(l);qread(r);qread(c);
105         sol(l,r,c);
106     }
107     return 0;
108 }

 

posted @ 2018-03-16 13:57  CHerish_OI  阅读(226)  评论(0编辑  收藏  举报