博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
雅礼集训2019 day5
阅读量:5120 次
发布时间:2019-06-13

本文共 4221 字,大约阅读时间需要 14 分钟。

matrix

在这里插入图片描述

n∗m≤5e5,1≤ai,j≤1e9n*m≤5e5,1≤a_{i,j}≤1e9nm5e5,1ai,j1e9
一道很妙的题。
首先大家应该都会无脑的O(nm2)dpO(nm^2)dpO(nm2)dp,即我们固定左右端点和之间的字符串SSS,从上往下扫计算每一行的贡献,对于第iii行的串SiS_iSi,我们设上一个出现的满足Sj=SiS_j=S_iSj=Si的位置为jjj,那么SiS_iSi对答案的贡献就是(i−j)∗(n−i+1)(i-j)*(n-i+1)(ij)(ni+1)
于是对于每一种串我们可以维护其出现位置的集合setS={a0,a1,a2,..,at}set_S=\{a_0,a_1,a_2,..,a_t\}setS={
a0,a1,a2,..,at}
,其中a0=0a_0=0a0=0是方便计算的,那么这个串的贡献就是∑i=1t(ai−ai−1)(n−ai+1)\sum_{i=1}^t(a_i-a_i-1)(n-a_i+1)i=1t(aiai1)(nai+1)
现在的问题变成了如何快速维护这个东西。
考虑先将lll强制为111,然后按行建立trietrietrie树,对于每个节点维护上面谈到的位置集合,然后可以统计出l=1l=1l=1时候的答案。
然后当l→l+1l\rightarrow l+1ll+1的时候,我们把当前根节点的所有儿子删掉,把所有儿子的儿子启发式合并起来即可。
代码:

#include
#define ri register int#define fi first#define se secondusing namespace std;const int rlen=1<<18|1;inline char gc(){
static char buf[rlen],*ib,*ob; (ib==ob)&&(ob=(ib=buf)+fread(buf,1,rlen,stdin)); return ib==ob?-1:*ib++;}inline int read(){
int ans=0; char ch=gc(); while(!isdigit(ch))ch=gc(); while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc(); return ans;}typedef long long ll;const int N=5e5+5;int n,m,a[N],rt=1,tot=1;map
son[N];set
pos[N];typedef map
::iterator It;ll ans=0,sum=0,val[N];inline void build(int id,int l,int r){
for(ri p=rt,v,i=l;i<=r;++i){
if(!son[p][a[i]])son[p][a[i]]=++tot,pos[son[p][a[i]]].insert(0),pos[son[p][a[i]]].insert(n+1); pos[v=son[p][a[i]]].insert(id); set
::iterator it=pos[v].lower_bound(id); --it,val[v]+=(ll)(id-*it)*(n-id+1); p=v; }}inline int merge(int x,int y){
if(!x||!y)return x+y; if(pos[x].size()
::iterator L=pos[y].begin(),R=pos[y].end(); ++L,--R; for(set
::iterator it=L,il,ir;it!=R;++it){ pos[x].insert(*it),il=ir=pos[x].lower_bound(*it),--il,++ir; val[x]+=(ll)(*it-*il)*(*ir-*it); }// pos[y].clear(); sum+=val[x]; for(It it=son[y].begin();it!=son[y].end();++it)son[x][it->fi]=merge(son[x][it->fi],it->se);// son[y].clear(); return x;}inline void update(){ static int stk[N],top=0; for(It it=son[rt].begin();it!=son[rt].end();++it)sum-=val[stk[++top]=it->se]; son[rt].clear(); while(top){ for(It it=son[stk[top]].begin();it!=son[stk[top]].end();++it)son[rt][it->fi]=merge(son[rt][it->fi],it->se); --top; }}int main(){ n=read(),m=read(); for(ri i=1,up=n*m;i<=up;++i)a[i]=read(); for(ri l=1,r=m,i=1;i<=n;++i,l+=m,r+=m)build(i,l,r); for(ri i=1;i<=tot;++i)sum+=val[i]; ans=sum; for(ri i=2;i<=m;++i)update(),ans+=sum; cout<

sequence

在这里插入图片描述

在这里插入图片描述
签到题(然而签到失败)
考虑离线处理,然后从右向左枚举左端点,看有哪些右端点满足条件。
每个位置作为起点向右只有logloglog种不同的结果,我们用链表维护一下这些结果然后用bitbitbit统计贡献即可。
代码:

#include
#define ri register int#define fi first#define se secondusing namespace std;const int rlen=1<<18|1;inline char gc(){
static char buf[rlen],*ib,*ob; (ib==ob)&&(ob=(ib=buf)+fread(buf,1,rlen,stdin)); return ib==ob?-1:*ib++;}inline int read(){
int ans=0; char ch=gc(); while(!isdigit(ch))ch=gc(); while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc(); return ans;}typedef pair
pii;typedef long long ll;const int N=1e5+5,M=5e5+5;int n,m,k,a[N],suf[N];ll ans[M];vector
qry[M];namespace Bit{
ll s1[N],s2[N]; inline int lowbit(const int&x){
return x&-x;} inline void update(const int&x,const int&v){
for(ri i=x;i<=n;i+=lowbit(i))s1[i]+=(ll)x*v,s2[i]+=v;} inline ll query(const int&x){
ll ret=0;for(ri i=x;i;i^=lowbit(i))ret+=(ll)(x+1)*s2[i]-s1[i];return ret;} inline void update(int l,int r,int v){
update(l,v),update(r+1,-v);}}int main(){
n=read(),m=read(),k=read(); for(ri i=1;i<=n;++i)a[i]=read(); for(ri i=1,x;i<=m;++i)x=read(),qry[x].push_back(pii(read(),i)); for(ri val,last,i=n;i;--i){
val=a[i],suf[i]=i+1,last=i; for(ri pre=i,p=i+1;p<=n;pre=p,p=suf[p]){
if((val&a[p])^val){
if(val==val/k*k)Bit::update(last,p-1,1); val&=a[p],last=p; } else suf[pre]=suf[p]; } if(val==val/k*k)Bit::update(last,n,1); for(ri j=0;j

permutation

在这里插入图片描述

在这里插入图片描述
一道简单的推式子题,原题是,但不知道为什么毒瘤出题人要卡O(nlogn2)O(nlog^2_n)O(nlogn2)的分治nttnttntt,行吧那么我们就用O(nlogn)O(nlog_n)O(nlogn)的倍增。
其实先考虑暴力dpdpdp,枚举最大值放哪里,然后发现需要把剩下n−1n-1n1个数放进a+b−2a+b-2a+b2个黑白环再钦定其中a−1a-1a1个为黑环剩余为白环,因此ans=s1n−1a+b−2Ca+b−2a−1ans=s1_{n-1}^{a+b-2}C_{a+b-2}^{a-1}ans=s1n1a+b2Ca+b2a1
倍增处理方法和代码看

转载于:https://www.cnblogs.com/ldxcaicai/p/11020450.html

你可能感兴趣的文章
状态栏的颜色设置
查看>>
left join 右表数据不唯一的情况解决方法
查看>>
java核心技术卷一
查看>>
页面响应式技巧-简摘
查看>>
laravel 如何引入自己的函数或类库
查看>>
Java中的hashCode 方法
查看>>
性能测试基础-开门篇2
查看>>
scala初体验3——控制
查看>>
NASA新项目:安卓手机变卫星 | 36氪
查看>>
【转】MySQL命令
查看>>
安装protobuf及相关的lua生成器
查看>>
MongoDB 更新文档
查看>>
django教程
查看>>
Linux centosVMware MySQL主从介绍、准备工作、配置主、配置从、测试主从同步
查看>>
C/C++由字符串转JSON/JSON转字符串/数组解析/数组添加
查看>>
web前端面试中CSS 相关问题
查看>>
struts2 学习笔记
查看>>
C/C++程序基础 (二)常用知识点
查看>>
bzoj1911 特别行动队
查看>>
gif动态图制作教程,gif录制软件推荐
查看>>