zoukankan      html  css  js  c++  java
  • HZOI20190823模拟31题解

    题面:https://www.cnblogs.com/Juve/articles/11425141.html

    math:仔细看看其实是个水题

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define int long long
    #define re register
    using namespace std;
    const int MAXN=5e5+5;
    const int MAXM=1e6+5;
    int n,k,a[MAXN],g,sum;
    int gcd(int a,int b){
    	return b==0?a:gcd(b,a%b);
    }
    signed main(){
    	scanf("%lld%lld",&n,&k);
    	for(re int i=1;i<=n;i++) scanf("%lld",&a[i]);
    	g=k;
    	for(int i=1;i<=n;i++) g=gcd(a[i],g);
    	sum=k/g;
    	printf("%lld
    ",sum);
    	for(int i=0;i*g<k;i++){
    		printf("%lld ",i*g);
    	}
    	puts("");
    	return 0;
    }
    

    biology:dp,维护4个最大值

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define MAXN 2005
    #define re register
    #define int long long
    using namespace std;
    int n,m,a[MAXN][MAXN],b[MAXN][MAXN],ans=0,tot=0,st;
    struct node{
    	int x,y,a,b;
    	friend bool operator < (node p,node q){
    		return p.a<q.a;
    	}
    }t[MAXN*MAXN];
    bool vis[MAXN*MAXN];
    int px1,px2,px3,px4,mx1,mx2,mx3,mx4;
    signed main(){
    	scanf("%lld%lld",&n,&m);
    	for(re int i=1;i<=n;i++)
    		for(re int j=1;j<=m;j++)
    			scanf("%lld",&a[i][j]);
    	for(re int i=1;i<=n;i++)
    		for(re int j=1;j<=m;j++){
    			scanf("%lld",&b[i][j]);
    			if(a[i][j]==0) continue;
    			t[++tot]=(node){i,j,a[i][j],b[i][j]};
    		}
    	sort(t+1,t+tot+1);
    	t[0]=t[1];
    	for(int i=1;i<=tot;i++) if(t[i].a!=t[i-1].a) vis[i]=1;
    	for(int i=1;i<=tot;i++){
    		int x=t[i].x,y=t[i].y,res=t[i].b;
    		if(vis[i]){
    			st=i;
    			break;
    		}
    		px1=max(px1,res-x-y);
    		px2=max(px2,res-x+y);
    		px3=max(px3,res+x-y);
    		px4=max(px4,res+x+y);
    	}
    	for(int i=st;i<=tot;i++){
    		int x=t[i].x,y=t[i].y,res=0;
    		if(vis[i]){
    			mx1=max(mx1,px1);
    			mx2=max(mx2,px2);
    			mx3=max(mx3,px3);
    			mx4=max(mx4,px4);
    			px1=px2=px3=px4=0;
    		}
    		res=max(max(mx1+x+y,mx2+x-y),max(mx3-x+y,mx4-x-y))+t[i].b;
    		px1=max(px1,res-x-y);
    		px2=max(px2,res-x+y);
    		px3=max(px3,res+x-y);
    		px4=max(px4,res+x+y);
    		ans=max(ans,res);
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    /*
    3 3
    0 6 8
    1 6 1
    0 6 8
    0 1 2
    3 4 5
    0 6 7
    */
    

    english:

    ans1用单调栈处理出每一个ai,它作为最大值的区间,然后维护前缀和,sum[i][j]表示前j个数第i位上有几个1

    ans2用可持久化01trie做

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define int long long
    using namespace std;
    const int MAXN=1e5+5;
    const int mod=1e9+7;
    int n,a[MAXN],opt,sum[22][MAXN],ans1=0,ans2=0;
    int sta[MAXN],top=0,l[MAXN],r[MAXN],tot=0;
    int tr[MAXN*22][2],size[MAXN*22],root[MAXN];
    void insert(int &now,int pre,int val,int i){
    	now=++tot;
    	size[now]=size[pre]+1;
    	if(i<0) return ;
    	int p=(val>>i)&1;
    	tr[now][p^1]=tr[pre][p^1];
    	insert(tr[now][p],tr[pre][p],val,i-1);
    	size[now]=size[tr[now][0]]+size[tr[now][1]];
    }
    int query(int rt,int x,int y){
    	int res=0;
    	for(int i=20;i>=0;i--){
    		int p=(x>>i)&1,q=(y>>i)&1;
    		if(!q){
    			(res+=size[tr[rt][p^1]])%=mod;
    			rt=tr[rt][p];
    		}
    		else rt=tr[rt][p^1];
    		if(!rt) break;
    	}
    	return res;
    }
    signed main(){
    	scanf("%lld%lld",&n,&opt);
    	for(int i=1;i<=n;i++){
    		scanf("%lld",&a[i]);
    		insert(root[i],root[i-1],a[i],20);
    		int tmp=a[i];
    		for(int j=0;j<=20;j++){
    			sum[j][i]=sum[j][i-1];
    			if((a[i]>>j)&1) sum[j][i]++;
    		}
    	}
    	for(int i=0;i<=20;i++) sum[i][n+1]=sum[i][n],sum[i][0]=0;
    	for(int i=1;i<=n;i++){
    		while(top!=0&&a[sta[top]]<a[i]) top--;
    		if(top==0) l[i]=1;
    		else l[i]=sta[top]+1;
    		sta[++top]=i;
    	}
    	top=0;
    	for(int i=n;i>=1;i--){
    		while(top!=0&&a[sta[top]]<=a[i]) top--;
    		if(top==0) r[i]=n+1;
    		else r[i]=sta[top];
    		sta[++top]=i;
    	}
    	for(int i=1,res;i<=n;i++){
    		res=0;
    		if(l[i]==r[i]) continue;
    		for(int j=0;j<=20;j++){
    			(res+=(((sum[j][i]-sum[j][l[i]-1])*((r[i]-i)-(sum[j][r[i]-1]-sum[j][i-1])))<<j))%=mod;
    			(res+=(((sum[j][r[i]-1]-sum[j][i-1])*((i-l[i]+1)-(sum[j][i]-sum[j][l[i]-1])))<<j))%=mod;
    		}
    		(ans1+=res*a[i]%mod)%=mod;
    		res=0;
    		if(i-l[i]<r[i]-i-1){
    			for(int j=l[i];j<=i;j++)
    				(res+=(query(root[r[i]-1],a[j],a[i])-query(root[i-1],a[j],a[i])+mod)%mod)%=mod;
    		}else{
    			for(int j=i;j<r[i];j++)
    				(res+=(query(root[i],a[j],a[i])-query(root[l[i]-1],a[j],a[i])+mod)%mod)%=mod;
    		}
    		(ans2+=(res*a[i]%mod))%=mod;
    	}
    	if(opt==1) printf("%lld
    ",ans1%mod);
    	else if(opt==2) printf("%lld
    ",ans2%mod);
    	else printf("%lld
    %lld
    ",ans1%mod,ans2%mod);
    	return 0;
    }
    
  • 相关阅读:
    天梯赛5-12 愿天下有情人都是失散多年的兄妹 【dfs】
    poj2718 Smallest Difference【贪心】
    HDU problem 5635 LCP Array【思维】
    codeforces 782C Andryusha and Colored Balloons【构造】
    HDU 4278 Faulty Odometer【进制转换】
    codeforces B. The Meeting Place Cannot Be Changed【二分】
    POJ 3264 Balanced Lineup 【线段树】
    HDU 1850
    CodeForces-714C
    HDU Problem 1247 Hat's Words 【字典树】
  • 原文地址:https://www.cnblogs.com/Juve/p/11425218.html
Copyright © 2011-2022 走看看