• [CLYZ2017]day2


    冒泡排序

    image

    Solution

    30分

    直接模拟.

    70分

    求出\(a\)中每个数之前比它大的数的个数,取\(max\).

    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<stack>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #define N 1000005
    using namespace std;
    typedef long long ll;
    int a[N],pre[N],n,s,b,c,d,cnt,ans;
    inline int read(){
    	int ret=0;char c=getchar();
    	while(!isdigit(c))
    		c=getchar();
    	while(isdigit(c)){
    		ret=(ret<<1)+(ret<<3)+c-'0';
    		c=getchar();
    	}
    	return ret;
    }
    inline bool chk(){
    	for(int i=1;i<=n;++i)
    		if(a[i]!=i)
    			return false;
    	return true; 
    }
    inline int lowbit(int x){
    	return x&(-x);
    }
    inline int ask(int k){
    	int ret=0;
    	for(int i=k;i;i-=lowbit(i))
    		ret+=pre[i];
    	return ret;
    }
    inline void add(int k){
    	for(int i=k;i<=n;i+=lowbit(i))
    		++pre[i];
    }
    inline void Aireen(){
    	scanf("%d%d%d%d%d",&n,&s,&b,&c,&d);
    	for(int i=1,j,t;i<=n;++i){
    		a[i]=i;
    		s=(1ll*s*b+c)%d;
     		swap(a[i],a[s%i+1]);
    	}
    	if(n<=1000){
    		int t;cnt=0;
    		while(!chk()){
    			++cnt;
    			for(int i=1;i<n;++i)
    				if(a[i]>a[i+1]){
    					t=a[i];a[i]=a[i+1];a[i+1]=t;
    				}
    		}
    		printf("%d\n",cnt);
    		return;
    	}
    	for(int i=1;i<=n;++i){
    		ans=max(ans,ask(n)-ask(a[i]));
    		add(a[i]);
    	}
    	printf("%d\n",ans);
    }
    int main(){
    	freopen("bubble.in","r",stdin);
    	freopen("bubble.out","w",stdout);
    	Aireen();
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    

    100分

    \(ans=max\{i-a_i\}\).

    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<stack>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #define N 30000005
    using namespace std;
    typedef long long ll;
    int a[N],n,s,b,c,d,ans;
    inline void Aireen(){
    	scanf("%d%d%d%d%d",&n,&s,&b,&c,&d);
    	for(register int i=1,j,t;i<=n;++i){
    		a[i]=i;
    		s=(1ll*s*b+c)%d;
     		swap(a[i],a[s%i+1]);
    	}
    	for(register int i=1;i<=n;++i)
    		ans=max(ans,i-a[i]);
    	printf("%d\n",ans);
    }
    int main(){
    	freopen("bubble.in","r",stdin);
    	freopen("bubble.out","w",stdout);
    	Aireen();
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    

    代码问题

    有些下标计算爆int.

    字符串匹配

    image

    Solution

    10分

    暴力求解.

    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<stack>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #define N 1000005
    using namespace std;
    typedef long long ll;
    int s[N],t[N],g[N],nxt[N],tot[N],ans[N],n,m,k,c,q,cnt,sum;
    bool b[N];
    inline int read(){
    	int ret=0;char c=getchar();
    	while(!isdigit(c))
    		c=getchar();
    	while(isdigit(c)){
    		ret=(ret<<1)+(ret<<3)+c-'0';
    		c=getchar();
    	}
    	return ret;
    }
    inline bool chk(int u){
    	for(int i=1;i<=c;++i) 
    		for(int j=g[i],k=s[u+g[i]];j;j=nxt[j]){
    			if(s[u+j]!=k) return false;
    		} 
    	return true;
    }
    inline void Aireen(){
    	q=read();c=read();
    	while(q--){
    		n=read();m=read();
    		for(int i=1;i<=n;++i)
    			s[i]=read();
    		for(int i=1;i<=m;++i)
    			t[i]=read();
    		memset(g,0,sizeof(g));
    		memset(b,0,sizeof(b));
    		memset(tot,0,sizeof(tot));
    		if(n<m){
    			puts("0");continue;
    		}
    		for(int i=m;i;--i){
    			nxt[i]=g[t[i]];
    			g[t[i]]=i;b[t[i]]=true;
    		}
    		k=cnt=sum=0;
    		for(int i=1;i<=c;++i)
    			if(b[i]) ++k;
    		for(int i=1;i<m;++i){
    			if(!tot[s[i]]) ++cnt;
    			++tot[s[i]];
    		}
    		for(int i=0;i+m<=n;++i){
    			if(!tot[s[i+m]]) ++cnt;
    			++tot[s[i+m]];
    			if(cnt==k&&chk(i))
    				ans[++sum]=i+1;
    			if(!(--tot[s[i+1]])) --cnt;
    		}
    		printf("%d\n",sum);
    		for(int i=1;i<=sum;++i)
    			printf("%d ",ans[i]);
    		printf("\n"); 
    	}
    }
    int main(){
    	freopen("match.in","r",stdin);
    	freopen("match.out","w",stdout);
    	Aireen();
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    

    100分

    对字符串相同字符间的相邻距离进行\(kmp\).
    会出现上一个相同字符不出现在目前匹配的子串中,在跳nxt的判断中,分类讨论即可.

    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<stack>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #define N 1000005
    using namespace std;
    int s[N],t[N],nxt[N],lst[N],ans[N],n,m,c,q,cnt;
    inline int read(){
    	int ret=0;char c=getchar();
    	while(!isdigit(c))
    		c=getchar();
    	while(isdigit(c)){
    		ret=(ret<<1)+(ret<<3)+c-'0';
    		c=getchar();
    	}
    	return ret;
    }
    inline bool chk1(int i,int j){
    	if(j<t[i]) return !t[j+1];
    	return t[j+1]==t[i];
    }
    inline bool chk2(int i,int j){
    	if(j<s[i]) return !t[j+1];
    	return t[j+1]==s[i];
    }
    inline void Aireen(){
    	q=read();c=read();
    	while(q--){
    		n=read();m=read();
    		for(int i=1;i<=n;++i)
    			s[i]=read();
    		for(int i=1;i<=m;++i)
    			t[i]=read();
    		if(n<m){
    			puts("0");continue;
    		}
    		memset(lst,0,sizeof(lst));
    		for(int i=1,k;i<=n;++i){
    			if(!lst[s[i]]) k=0;
    			else k=i-lst[s[i]];
    			lst[s[i]]=i;s[i]=k;
    		}
    		s[n+1]=t[m+1]=-1;
    		memset(lst,0,sizeof(lst));
    		for(int i=1,k;i<=m;++i){
    			if(!lst[t[i]]) k=0;
    			else k=i-lst[t[i]];
    			lst[t[i]]=i;t[i]=k;
    		}
    		cnt=0;
    		memset(nxt,0,sizeof(nxt));
    		for(int i=2,j=0;i<=m;++i){
    			while(j&&!chk1(i,j)) j=nxt[j];
    			if(chk1(i,j)) ++j;
    			nxt[i]=j;
    		}
    		for(int i=1,j=0;i<=n;++i){
    			while(j&&!chk2(i,j)) j=nxt[j];
    			if(chk2(i,j)) ++j;
    			if(j==m){
    				ans[++cnt]=i-m+1;
    				j=nxt[j];
    			}
    		}
    		printf("%d\n",cnt);
    		for(int i=1;i<=cnt;++i)
    			printf("%d ",ans[i]);
    		printf("\n");
    	}
    }
    int main(){
    	freopen("match.in","r",stdin);
    	freopen("match.out","w",stdout);
    	Aireen();
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    

    阅读

    image

    Solution

    20分

    \(f[i]=max\{f[j]-\lceil\frac{t[i]-t[j]}{D}\rceil\times{A}\}+b[i]\).

    50分

    对于\(D\leq100\),对于每个\(t_i\;mod\;D\)同余的贪心.枚举\(mod\;D\)不同的值即可.

    100分

    可以发现,
    \(t[j]<t[i]\)时,\(\lceil\frac{t[i]-t[j]}{D}\rceil=\lfloor\frac{t[i]}{D}\rfloor-\lfloor\frac{t[j]}{D}\rfloor+1\);
    \(t[j]\geq{t[i]}\)时,\(\lceil\frac{t[i]-t[j]}{D}\rceil=\lfloor\frac{t[i]}{D}\rfloor-\lfloor\frac{t[j]}{D}\rfloor\);
    \(f[i]-\lfloor\frac{m}{D}\rfloor-\lfloor\frac{k}{D}\rfloor=max\{max\{f[1...j-1]\}-a,max\{f[j...m]\}\}\)
    (\(j\)表示\(mod\;D\)的值离散后的位置,离散后共有m个值).
    最后全部加上\(\lfloor\frac{m}{D}\rfloor-\lfloor\frac{k}{D}\rfloor\)就好啦.
    P.S.写代码的时候比较傻,所以写得正确性和简洁性堪忧.

    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<stack>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #define N 100005
    #define M 300005
    using namespace std;
    typedef long long ll;
    ll f[N],g[N],b[N],t[N],a,d,m,k,ans;
    int p[N],idp[N],ids[N],n,cnt;
    inline int read(){
    	int ret=0;char c=getchar();
    	while(!isdigit(c))
    		c=getchar();
    	while(isdigit(c)){
    		ret=(ret<<1)+(ret<<3)+c-'0';
    		c=getchar();
    	}
    	return ret;
    }
    //i比j优 
    inline bool cmp(int i,int j){
    	return f[i]+t[i]/d*a>f[j]+t[j]/d*a;
    }
    inline int lowbit(int k){
    	return k&(-k);
    }
    inline void change(int k){
    	for(int i=k;i<=cnt;i+=lowbit(i))
    		if(!idp[i]||cmp(g[k],idp[i])) idp[i]=g[k]; 
    	for(int i=cnt-k+1;i<=cnt;i+=lowbit(i)){
    		if(!ids[i]||cmp(g[k],ids[i])) ids[i]=g[k];
    	}
    }
    inline int pre(int k){
    	int ret=0;
    	for(int i=k;i;i-=lowbit(i))
    		if(!ret) ret=idp[i];
    		else if(cmp(idp[i],ret))
    			ret=idp[i];
    	return ret;
    }
    inline int suf(int k){
    	int ret=0;
    	for(int i=cnt-k+1;i;i-=lowbit(i))
    		if(!ret) ret=ids[i];
    		else if(cmp(ids[i],ret))
    			ret=ids[i];
    	return ret;
    }
    inline void Aireen(){
    	scanf("%lld%lld%lld%lld%d",&k,&m,&d,&a,&n);
    	for(int i=1;i<=n;++i)
    		scanf("%lld%lld",&t[i],&b[i]);
    	if(n<=1000){
    		for(int i=1;i<=n;++i){
    			if((t[i]-k)%d) f[i]=-((t[i]-k)/d+1ll)*a+b[i];
    			else f[i]=-(t[i]-k)/d*a+b[i];
    			for(int j=1;j<i;++j)
    				if((t[i]-t[j])%d)
    					f[i]=max(f[i],f[j]-((t[i]-t[j])/d+1ll)*a+b[i]);
    				else f[i]=max(f[i],f[j]-(t[i]-t[j])/d*a+b[i]);
    		}
    		if((m-k)%d) ans=-((m-k)/d+1ll)*a;
    		else ans=-(m-k)/d*a;
    		for(int i=1;i<=n;++i)
    			if((m-t[i])%d)
    				ans=max(ans,f[i]-((m-t[i])/d+1ll)*a);
    			else ans=max(ans,f[i]-(m-t[i])/d*a);
    		printf("%lld\n",ans);
    		return;
    	}
    	if(d<=100){
    		for(int i=1;i<=n;++i){
    			if((t[i]-k)%d) f[i]=-((t[i]-k)/d+1ll)*a+b[i];
    			else f[i]=-(t[i]-k)/d*a+b[i];
    			for(int k=(int)(d-1ll),j;k>=0;--k)
    				if((t[i]-t[j=g[k]])%d)
    					f[i]=max(f[i],f[j]-((t[i]-t[j])/d+1ll)*a+b[i]);
    				else f[i]=max(f[i],f[j]-(t[i]-t[j])/d*a+b[i]);
    			if(!g[t[i]%d]) g[t[i]%d]=i;
    			else if(cmp(i,g[t[i]%d]))
    				g[t[i]%d]=i;
    		}
    		if((m-k)%d) ans=-((m-k)/d+1ll)*a;
    		else ans=-(m-k)/d*a;
    		for(int i=1;i<=n;++i)
    			if((m-t[i])%d)
    				ans=max(ans,f[i]-((m-t[i])/d+1ll)*a);
    			else ans=max(ans,f[i]-(m-t[i])/d*a);
    		printf("%lld\n",ans);
    		return;	
    	}
    	for(int i=1;i<=n;++i)
    		p[i]=(int)(t[i]%d);
    	sort(p+1,p+1+n);cnt=1;
    	for(int i=2;i<=n;++i)
    		if(p[i]!=p[i-1]) p[++cnt]=p[i];
    	for(int i=1,j,l;i<=n;++i){
    		if((t[i]-k)%d) f[i]=-((t[i]-k)/d+1ll)*a+b[i];
    		else f[i]=-(t[i]-k)/d*a+b[i];
    		l=lower_bound(p+1,p+1+cnt,(int)(t[i]%d))-p;
    		if(l-1){
    			j=pre(l-1);
    			if(j){
    				if((t[i]-t[j])%d) 
    					f[i]=max(f[i],f[j]-((t[i]-t[j])/d+1ll)*a+b[i]);
    				else f[i]=max(f[i],f[j]-(t[i]-t[j])/d*a+b[i]);
    			}
    		}
    		j=suf(l);
    		if(j){
    			if((t[i]-t[j])%d) 
    				f[i]=max(f[i],f[j]-((t[i]-t[j])/d+1ll)*a+b[i]);
    			else f[i]=max(f[i],f[j]-(t[i]-t[j])/d*a+b[i]);
    		}
    		if(!g[l]){
    			g[l]=i;change(l);
    		}
    		else if(cmp(i,g[l])){
    			g[l]=i;change(l);
    		}
    	}
    	if((m-k)%d) ans=-((m-k)/d+1ll)*a;
    	else ans=-(m-k)/d*a;
    	for(int i=1;i<=n;++i)
    		if((m-t[i])%d)
    			ans=max(ans,f[i]-((m-t[i])/d+1ll)*a);
    		else ans=max(ans,f[i]-(m-t[i])/d*a);
    	printf("%lld\n",ans);
    }
    int main(){
    	freopen("reading.in","r",stdin);
    	freopen("reading.out","w",stdout);
    	Aireen();
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    用mysql+redis实现微博feed架构上需要注意哪些问题
    windows7下安装zend studio5.5
    鼠标移出DIV层时,触发onMouseOut事件
    关于MVVM和RAC的一些拓展阅读
    Swift(上) 常量, 变量, 数据类型, 循环, 选择结构 简单函数
    SDWebImage的使用
    App Store新应用提审攻略
    关于iOS的推送服务的点点
    iOS开发代码规范
    伟大的RAC和MVVM入门(二)
  • 原文地址:https://www.cnblogs.com/AireenYe/p/CLYZ2017day2.html
Copyright © 2020-2023  润新知