题面: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; }