A.math

考场乱搞拿了95,2333。

考虑裴蜀定理:$ax+by=z$存在整数解,当且仅当$gcd(a,b)|z$。

那么如果某个数能够被拼出来,就必须满足所有$a_i$的$gcd$是它的因子。直接枚举倍数即可。

//代码来自DeepinC
#include<cstdio>
int n,k,g,x;
int gcd(int a,int b){return b?gcd(b,a%b):a;}
int main(){
scanf("%d%d",&n,&k);g=k;
while(n--)scanf("%d",&x),g=gcd(g,x);
printf("%d\n",k/g);
for(int i=0;i<k;i+=g)printf("%d ",i);
}

B.biology

首先将$a[i][j]$离散化,值相同的方格坐标都放到一起。然后很容易得到一个暴力的dp:$f[i][j]=max{f[i'][j']+|i-i'|+|j-j'|}$,$i',j'$位于a值比$i,j$小的上一层。

最劣复杂度会达到$O(n^2m^2)$,考虑优化。可以把绝对值用分类讨论拆开,四个树状数组分别维护$f[i][j]-i-j,f[i][j]-i+j,f[i][j]+i-j,f[i][j]+i+j$的最大值,转移时先分别查询以$i,j$为中心的四块区域的最优值,用最大的更新$f[i][j]$,之后再分别把$f[i][j]$上传到树状数组里。注意要用前缀最大值查询四块的最优值来保证log的复杂度,所以需要把坐标反转一下。

正解其实就是把树状数组去掉……我们用树状数组维护四部分的最大值是为了保证在合法的情况下转移最优,但本题的特殊性使不合法的情况一定没有合法情况优(如果你绝对值去的不对就会让坐标差变成负的),所以直接用四个变量维护四部分的最大值即可。我把坐标转换了一下,即$(i,j)->(i+j,i-j)$,其实不转换也是可以的。

//80分树状数组
#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
#define pa pair<int,int>
#define QWQ dp[x][y]=max(dp[x][y],maxx)
using namespace std;
typedef long long ll;
int read()
{
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return x*f;
}
const int N=2005,M=1e6+5;
int n,m;
int a[N][N],b[N][N];
struct bit
{
ll c[N][N];
int lb(int x){return x&-x;}
void update(int x,int y,ll val)
{
for(int i=x;i<=n;i+=lb(i))
for(int j=y;j<=m;j+=lb(j))
c[i][j]=max(val,c[i][j]);
}
ll query(int x,int y)
{
ll res=0;
for(int i=x;i;i-=lb(i))
for(int j=y;j;j-=lb(j))
res=max(res,c[i][j]);
return res;
}
}c1,c2,c3,c4;
int app[M],key[M],cnt,num[M];
vector<pa> fl[M];
ll dp[N][N];
int main()
{
n=read();m=read();
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
a[i][j]=read();
if(!app[a[i][j]]&&a[i][j])
{
app[a[i][j]]=1;
num[++cnt]=a[i][j];
}
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
b[i][j]=read();
sort(num+1,num+cnt+1);
for(int i=1;i<=cnt;i++)
key[num[i]]=i;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(!a[i][j])continue;
fl[key[a[i][j]]].push_back(make_pair(i,j));
}
int sz=fl[1].size();
for(int i=0;i<sz;i++)
{
int x=fl[1][i].first,y=fl[1][i].second;
c1.update(x,y,b[x][y]-x-y);
c2.update(x,m-y+1,b[x][y]-x+y);
c3.update(n-x+1,y,b[x][y]+x-y);
c4.update(n-x+1,m-y+1,b[x][y]+x+y);
}
for(int i=2;i<=cnt;i++)
{
sz=fl[i].size();
for(int j=0;j<sz;j++)
{
int x=fl[i][j].first,y=fl[i][j].second;
ll maxx=0;
maxx=c1.query(x,y)+x+y+b[x][y];QWQ;
maxx=c2.query(x,m-y+1)+x-y+b[x][y];QWQ;
maxx=c3.query(n-x+1,y)-x+y+b[x][y];QWQ;
maxx=c4.query(n-x+1,m-y+1)-x-y+b[x][y];QWQ;
//cout<<x<<' '<<y<<' '<<dp[x][y]<<endl;
}
for(int j=0;j<sz;j++)
{
int x=fl[i][j].first,y=fl[i][j].second;
c1.update(x,y,dp[x][y]-x-y);
c2.update(x,m-y+1,dp[x][y]-x+y);
c3.update(n-x+1,y,dp[x][y]+x-y);
c4.update(n-x+1,m-y+1,dp[x][y]+x+y);
//cout<<x<<' '<<y<<' '<<dp[x][y]<<endl;
}
}
sz=fl[cnt].size();
ll ans=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
ans=max(ans,dp[i][j]);
cout<<ans<<endl;
return 0;
}
//AC
#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
#define pa pair<int,int>
using namespace std;
typedef long long ll;
int read()
{
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return x*f;
}
const int N=2005,M=1e6+5;
int n,m;
int a[N][N],b[N][N];
int app[M],key[M],cnt,num[M];
vector<pa> fl[M];
ll dp[N][N];
int getx(int i,int j){return (i+j)/2;}
int gety(int i,int j){return (i-j)/2;}
int main()
{
n=read();m=read();
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
a[i][j]=read();
if(!app[a[i][j]]&&a[i][j])
{
app[a[i][j]]=1;
num[++cnt]=a[i][j];
}
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
b[i][j]=read();
sort(num+1,num+cnt+1);
for(int i=1;i<=cnt;i++)
key[num[i]]=i;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(!a[i][j])continue;
fl[key[a[i][j]]].push_back(make_pair(i+j,i-j));
}
ll c1=-0x3f3f3f3f,c2=-0x3f3f3f3f,c3=-0x3f3f3f3f,c4=-0x3f3f3f3f;
int sz=fl[1].size();
for(int i=0;i<sz;i++)
{
int x=fl[1][i].first,y=fl[1][i].second,ox=getx(x,y),oy=gety(x,y);
c1=max(c1,1LL*b[ox][oy]-x);
c2=max(c2,1LL*b[ox][oy]+x);
c3=max(c3,1LL*b[ox][oy]-y);
c4=max(c4,1LL*b[ox][oy]+y);
}
for(int i=2;i<=cnt;i++)
{
sz=fl[i].size();
for(int j=0;j<sz;j++)
{
int x=fl[i][j].first,y=fl[i][j].second,ox=getx(x,y),oy=gety(x,y);
ll maxx=max(max(c1+ox+oy,c2-ox-oy),max(c3+ox-oy,c4-ox+oy));
dp[ox][oy]=maxx+b[ox][oy];
}
for(int j=0;j<sz;j++)
{
int x=fl[i][j].first,y=fl[i][j].second,ox=getx(x,y),oy=gety(x,y);
c1=max(c1,dp[ox][oy]-x);
c2=max(c2,dp[ox][oy]+x);
c3=max(c3,dp[ox][oy]-y);
c4=max(c4,dp[ox][oy]+y);
}
}
ll ans=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
ans=max(ans,dp[i][j]);
cout<<ans<<endl;
return 0;
}

C.english

对于每一个$i\in n$,求出$a[i]$作为最大值的范围$[l,r]$,可以用单调栈实现。

维护一个前缀和,$f[x][i]$表示1~x的区间里第i位是1的数有多少个。

用启发式合并的思路,对于每一个区间x,看它的左右儿子区间$[l,x-1]$和$[x+1,r]$哪个长度更大,以右儿子长度大为例:

枚举左区间的每一个数$a[i]$,并枚举它的每一位,如果这一位是0,那么对ans1的贡献就是$2^i \times (f[r][i]-f[x-1]) \times a[x]$。如果是1同理。

对ans2的贡献就是右区间中有多少个数$xor\ a[i]$后$>a[x]$,再乘上$a[x]$。区间问题用可持久化Trie解决。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<stack>
#include<algorithm>
#include<map>
//#define int long long
using namespace std;
int read()
{
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
typedef long long ll;
const int N=1e5+5;
const ll mod=1e9+7;
int n,a[N],op;
int le[N],re[N];
ll f[N][22];
stack<int> s;
ll ans1,ans2;
namespace Trie
{
int ch[N*22][2],size[N*22],type,root[N];
void ins(int pre,int &now,int i,ll x)
{
now=++type;
size[now]=size[pre];
if(i<0){size[now]++;return ;}
int d=(x>>i)&1;
ch[now][d^1]=ch[pre][d^1];
ins(ch[pre][d],ch[now][d],i-1,x);
size[now]=size[ch[now][0]]+size[ch[now][1]];
return ;
}
void ins(ll x,int pos){ins(root[pos-1],root[pos],20,x);}
ll query(int x,int y,int pos)
{
int p=root[pos],res=0;
for(int i=20;i>=0;i--)
{
int a=(x>>i)&1,b=(y>>i)&1;
if(b==0)
{
res+=size[ch[p][a^1]];
p=ch[p][a];
}
else p=ch[p][a^1];
if(!p)break;
}
return res;
}
}
void cacl(int k,int l,int r)
{
if(k-l<r-k)
{
for(int j=l;j<=k;j++)
{
(ans1+=1LL*a[j]*a[k]%mod*(r-k+1)%mod)%=mod;
for(int i=20;i>=0;i--)
{
int now=(a[j]>>i)&1;
if(!now)(ans1+=1LL*(1<<i)*(f[r][i]-f[k-1][i])%mod*a[k]%mod)%=mod;
else (ans1-=1LL*(1<<i)*(f[r][i]-f[k-1][i])%mod*a[k]%mod)%=mod,ans1=(ans1+mod)%mod;
}
ans2=(ans2+1LL*(Trie::query(a[j],a[k],r)-Trie::query(a[j],a[k],k-1)+mod)%mod*a[k]%mod)%mod;
}
}
else
{
for(int j=k;j<=r;j++)
{
(ans1+=1LL*a[j]*a[k]%mod*(k-l+1)%mod)%=mod;
for(int i=20;i>=0;i--)
{
int now=(a[j]>>i)&1;
if(!now)(ans1+=1LL*(1<<i)*(f[k][i]-f[l-1][i])%mod*a[k]%mod)%=mod;
else (ans1-=1LL*(1<<i)*(f[k][i]-f[l-1][i])%mod*a[k]%mod)%=mod,ans1=(ans1+mod)%mod;
}
ans2=(ans2+1LL*(Trie::query(a[j],a[k],k)-Trie::query(a[j],a[k],l-1)+mod)%mod*a[k]%mod)%mod;
}
}
} signed main()
{
n=read();op=read();
for(int i=1;i<=n;i++)
a[i]=read(),Trie::ins(a[i],i);
for(int i=1;i<=n;i++)
{
for(int j=0;j<=20;j++)
{
f[i][j]+=f[i-1][j];
if((a[i]>>j)&1)f[i][j]++;
}
}
for(int i=1;i<=n;i++)
{
while(!s.empty()&&a[i]>a[s.top()])s.pop();
le[i]=s.empty()?1:s.top()+1;
s.push(i);
}
while(!s.empty())s.pop();
for(int i=n;i;i--)
{
while(!s.empty()&&a[i]>=a[s.top()])s.pop();
re[i]=s.empty()?n:s.top()-1;
s.push(i);
}
for(int i=1;i<=n;i++)
cacl(i,le[i],re[i]);
if(op==1||op==3)cout<<ans1<<endl;
if(op==2||op==3)cout<<ans2<<endl;
/*for(int i=1;i<=n;i++)
cout<<i<<' '<<le[i]<<' '<<re[i]<<endl;*/
return 0;
}
/*
g++ -std=c++11 1.cpp -o 1
./1
*/

最新文章

  1. WebView随学笔记
  2. 关于nodejs能同时接受多少个请求的问题?////zzz
  3. javascript网址收集
  4. jquery 中post 、get的同步问题
  5. Android ListView onItemClick Not Work
  6. oracle11g dataguard 安装手册(转)
  7. XE6移动开发环境搭建之IOS篇(3):配置虚拟机,设置Mac安装环境(有图有真相)
  8. java类中serialversionuid 作用 是什么?举个例子说明
  9. .bak文件在英文版的sqlserver2014如何生成和恢复
  10. cocos2d-x中的导演、场景、层和精灵
  11. springboot情操陶冶-web配置(七)
  12. MySQL执行计划复习
  13. 最近的AI
  14. 洛谷P4213 Sum(杜教筛)
  15. Linux学习笔记 11
  16. 8 -- 深入使用Spring -- 7...2 MVC框架与Spring整合的思考
  17. MySQL 数据库--权限管理
  18. 沉淀再出发:dubbo的基本原理和应用实例
  19. [How to] 使用HBase协处理器---Endpoint服务端的实现
  20. ionic3 打包发布,以安卓说明

热门文章

  1. sql优化工具SQLAdvisor的安装
  2. 通过生成HFile导入HBase
  3. Deepin环境下安装科学研究版Python和Pytorch--防网卡
  4. qq传文件测试用例设计
  5. redis的set()方法参数
  6. IE兼容模式下样式分离错乱,求CSS高手
  7. undefined,null,var 0 = {},var s = &#39;&#39;,的区别
  8. Java script-1
  9. ios开发之UIView和UIViewController
  10. JS同行绑定事件