• Codeforces 543E. Listening to Music


    Description

    题面

    Solution

    分块套分块,分别对时间和位置进行分块
    差不多是一个定期保存信息的方法
    对于询问我们不妨求出 (>=x) 的答案,然后用 (m-(>=x)) 的答案,避免了严格小于带来的麻烦
    暴力做法是把数字从大到小加入,然后每一次做区间修改,主席树维护一下,但空间复杂度太大
    我们同样这么做,想办法均摊时间和空间复杂度
    我们设定一个 (S),每过 (S) 的时间就将主席树维护的东西暴力存下来
    但是暴力存下来空间开不下,我们想办法对序列分块,分别保存每一个块内的最大值
    每一个时刻的修改,我们就对块外暴力做,块内打标记,因为我们每过 (S) 的时间就要暴力存,留到这个时候再放标记,大致就是这样

    inline void Modify(int k,int l,int r){
    	if(b[l]==b[r]){
    		for(int i=l;i<=r;i++)w[i]++;
    		return ;
    	}
       for(int i=l;i<=br[b[l]];i++)w[i]++;
    	for(int i=b[l]+1;i<b[r];i++)la[i]++;
    	for(int i=bl[b[r]];i<=r;i++)w[i]++;
    }
    

    每过 (S) 时间我们暴力存下来,(f[k][i]) 表示前 (k) 个时刻的块,第 (i) 个块的 (F) 的最大值, (st[k][i]) 表示每一个块开头的 (F)

    inline void rec(int k){
    	for(int i=1;i<=cnt;i++){
    		for(int j=bl[i];j<=br[i];j++)
    			f[k][i]=max(f[k][i],w[j]+=la[i]);
    		st[k][i]=w[bl[i]];la[i]=0;
    	}
    }
    

    对于询问,对于 (>x) 的块,我们只关心每一个块的最值,我们直接把 (f) 数组拿来用就行了,然后就是 (x) 所在块内的修改
    我们还是按照 (Modify) 函数那样暴力改,但是每改一次需要花费 (O(S)) 的时间,复杂度不太对,但实际上这样有很多重复的计算
    我们实际上是把某些块做区间加法 , 同一块内的元素相对值不变,所以最值也不会改变,用差分维护一下最值的增量就行了
    块外的元素会改变,我们直接把改变之后的值记下来就好了
    所以预处理出 (pre[i],suf[i]) 表示第 (i) 时刻的修改之后,这两个块外的元素所在的块的最值
    这样一次修改复杂度就是 (O(1)) 的了

    #include<bits/stdc++.h>
    using namespace std;
    const int N=200010,M=510;
    int n,m,lis[N],a[N],bc,b[N],bl[N],br[N],p[N],cnt,v[N];
    int f[M][M],la[N],w[N],st[M][M],pre[N],suf[N],ed[N];
    inline bool comp(int i,int j){return a[i]>a[j];}
    inline void Modify(int k,int l,int r){
    	if(b[l]==b[r]){
    		for(int i=l;i<=r;i++)w[i]++;
    		for(int i=bl[b[l]];i<=br[b[l]];i++)pre[k]=max(pre[k],w[i]);
    		return ;
    	}
       for(int i=l;i<=br[b[l]];i++)w[i]++;
    	for(int i=bl[b[l]];i<=br[b[l]];i++)pre[k]=max(pre[k],w[i]);
    	for(int i=b[l]+1;i<b[r];i++)la[i]++;
    	for(int i=bl[b[r]];i<=r;i++)w[i]++;
    	for(int i=bl[b[r]];i<=br[b[r]];i++)suf[k]=max(suf[k],w[i]);
    }
    inline void rec(int k){
    	for(int i=1;i<=cnt;i++){
    		for(int j=bl[i];j<=br[i];j++)
    			f[k][i]=max(f[k][i],w[j]+=la[i]);
    		st[k][i]=w[bl[i]];la[i]=0;
    	}
    }
    inline int qry(int l,int r,int k,int x){
    	int now=v[k],ret=0;
    	for(int i=bl[k];i<l;i++)now+=(a[i+m]>=x)-(a[i]>=x);
    	for(int i=l;i<=r;i++)ret=max(ret,now),now+=(a[i+m]>=x)-(a[i]>=x);
    	return ret;
    }
    int main(){
      freopen("pp.in","r",stdin);
      freopen("pp.out","w",stdout);
      scanf("%d%d",&n,&m);bc=sqrt(n);
      for(int i=1;i<=n;i++)scanf("%d",&a[i]),lis[i]=a[i],p[i]=i;
      sort(lis+1,lis+n+1);
      int tp=unique(lis+1,lis+n+1)-lis-1,Q,ans=0;
      for(int i=1;i<=n;i++)a[i]=lower_bound(lis+1,lis+tp+1,a[i])-lis;
      for(int i=1,t;i<=n;i++)t=b[i]=(i-1)/bc+1,bl[t]=bl[t]?bl[t]:i,br[t]=i;
      sort(p+1,p+n+1,comp);cnt=b[n];
      for(int i=1;i<=n;i++){
    	  Modify(i,max(1,p[i]-m+1),p[i]);
    	  if(b[i]!=b[i+1])rec(b[i]),ed[b[i]]=a[p[i]];
      }
      cin>>Q;
      while(Q--){
    	  int l,r,x,t=1;
    	  scanf("%d%d%d",&l,&r,&x);
    	  x=lower_bound(lis+1,lis+tp+1,x^ans)-lis;
    	  while(t<cnt && ed[t]>=x)t++;
    	  for(int i=1;i<=cnt;i++)w[i]=f[t-1][i],v[i]=st[t-1][i],la[i]=0;
    	  for(int i=bl[t];i<=br[t] && a[p[i]]>=x;i++){
    		  int L=max(1,p[i]-m+1),R=p[i],A=b[L],B=b[R];
    		  if(A==B)w[A]=pre[i];
    		  else{
    			  w[A]=pre[i];w[B]=suf[i];
    			  la[A+1]++;la[B]--;
    		  }
    		  if(L<=bl[b[l]] && bl[b[l]]<=R)v[b[l]]++;
    		  if(b[l]!=b[r] && L<=bl[b[r]] && bl[b[r]]<=R)v[b[r]]++;
    	  }
    	  for(int i=1;i<=cnt;i++)la[i]+=la[i-1];
    	  int A=b[l],B=b[r];
    	  if(A==B)ans=qry(l,r,A,x);
    	  else{
    		  ans=max(qry(l,br[A],A,x),qry(bl[B],r,B,x));
    		  for(int i=A+1;i<B;i++)ans=max(ans,la[i]+w[i]);
    	  }
    	  ans=m-ans;
    	  printf("%d
    ",ans);
      }
      return 0;
    }
    
    
  • 相关阅读:
    HTTP长连接、短连接使用及测试
    递归分治算法之二维数组二分查找(Java版本)
    Java二维数组的概念和使用方法
    java二维数组遍历
    HashMap多线程并发问题分析
    Linux 移动或重命名文件/目录-mv 的10个实用例子
    CSS fixed 定位元素失效的问题
    关于 JavaScript 中的继承
    React 虚拟 DOM 的差异检测机制
    下拉框中选项的快速定位
  • 原文地址:https://www.cnblogs.com/Yuzao/p/8724712.html
Copyright © 2020-2023  润新知