zoukankan      html  css  js  c++  java
  • Password [分块]

    题面

    $n,m,x leq 10^5$

    思路

    首先$n=2$做法很多,不讲了

    $n=3$的时候,分块维护两个东西:每一个数出现次数的前缀和,和出现次数的出现次数的前缀和(说的有点绕,但是应该挺好理解的)

    然后会发现,第4行等于第2行,5=3,6=4......

    然后就做完了

    细节看代码吧

    Code

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cassert>
    #include<cmath>
    #define ll long long
    using namespace std;
    inline int read(){
    	int re=0,flag=1;char ch=getchar();
    	while(!isdigit(ch)){
    		if(ch=='-') flag=-1;
    		ch=getchar();
    	}
    	while(isdigit(ch)) re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
    	return re*flag;
    }
    int n,m,a[1000010],cnt[310][100010],pre[310][200010],cur[100010];
    int blk,tot;
    inline int op(int num){return blk*(num-1)+1;}
    inline int ed(int num){return min(blk*num,n);}
    inline int id(int num){return num/blk+(num%blk!=0);}
    inline void change(int pos,int val){
    	int p=id(pos),i;
    	for(i=p;i<=tot;i++) pre[i][cnt[i][a[pos]]]--;
    	for(i=p;i<=tot;i++) cnt[i][a[pos]]--;
    	a[pos]=val;
    	for(i=p;i<=tot;i++) cnt[i][a[pos]]++;
    	for(i=p;i<=tot;i++) pre[i][cnt[i][a[pos]]]++;
    }
    inline void build(){
    	int i,j;
    	for(j=1;j<=tot;j++){
    		for(i=1;i<=ed(j);i++)
    			cnt[j][a[i]]++;
    	}
    	for(j=1;j<=tot;j++){
    		memset(cur,0,sizeof(cur));
    		for(i=1;i<=ed(j);i++){
    			cur[a[i]]++;
    			pre[j][cur[a[i]]]++;
    		}
    	}
    }
    inline int query(int x,int pos){
    	if(x==1) return a[pos];
    	int i,sum=0,p=id(pos);x--;
    	sum=cnt[p-1][a[pos]];
    	for(i=op(p);i<=pos;i++) sum+=(a[i]==a[pos]);
    	if(x&1) return sum;
    	int re=pre[p-1][sum];
    	for(i=op(p);i<=pos;i++){
    		cnt[p-1][a[i]]++;
    		re+=(cnt[p-1][a[i]]==sum);
    	}
    	for(i=op(p);i<=pos;i++) cnt[p-1][a[i]]--;
    	return re;
    }
    int main(){
    	n=read();int i,t1,t2,t3;
    	for(i=1;i<=n;i++) a[i]=read();
    	blk=400;tot=n/blk+(n%blk!=0);
    	build();
    	m=read();
    	while(m--){
    		t1=read();t2=read();t3=read();
    		if(t1==1) change(t3,t2);
    		else printf("%d
    ",query(t2,t3));
    	}
    }
    
  • 相关阅读:
    yarn-cli 缓存
    html DOM 的继承关系
    JavaScript basics: 2 ways to get child elements with JavaScript
    svn merge 的区别
    virtualbox 设置windows 于ubuntu虚拟机共享文件夹
    angular 学习理解笔记
    e.which
    痛定思痛
    【转】反思 成长
    日语学习词汇量
  • 原文地址:https://www.cnblogs.com/dedicatus545/p/10073946.html
Copyright © 2011-2022 走看看