有一个数组开大会MLE开小会RE的做法:就是树套树,即树状数组套主席树,这种方法比较暴力,然而很遗憾它不能通过,因为其时空复杂度均为O(nlog2n)。

想到一种不怎么耗内存,以时间换空间,分块!单次修改(l,r)只对点对(l,r)、(l,i)和(i,r)产生影响,其中l<i<r,然后可以考虑分块,每块维护每个p[i]出现的次数,交换时块内直接查询即可,而修改也可以直接修改,套上树状数组即可在O(logn)内的时间维护。设块大小为k,时间复杂度为O(nlogn+mk+mnlogn/k),当k取√(nlogn)时,复杂度最优,此时复杂度为O(nlogn+m√(nlogn))。空间复杂度也不会爆炸,为O(n√n)。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e4+,mod=1e9+;
int n,m,B,p[N];
ll ans,s[][][N],v[N];
void add(int t,int id,int x,ll v)
{
if(!x)return;
while(x<=n)s[t][id][x]=(s[t][id][x]+v+mod)%mod,x+=x&-x;
}
ll ask(int t,int id,int x)
{
if(x<)return ;
ll ret=;while(x)ret=(ret+s[t][id][x])%mod,x-=x&-x;
return ret;
}
void calc(int a,int b,int c)
{
if(p[a]<p[c])ans=(ans+v[a]+v[c])%mod;else ans=(ans-v[a]-v[c]+*mod)%mod;
if(p[b]<p[c])ans=(ans-v[b]-v[c]+*mod)%mod;else ans=(ans+v[b]+v[c])%mod;
}
int main()
{
scanf("%d%d",&n,&m),B=sqrt(n*);
for(int i=;i<n;i++)scanf("%d%lld",&p[i],&v[i]),add(,i/B,p[i],v[i]),add(,i/B,p[i],);
for(int i=n-;~i;i--)
{
ans=(ans+ask(,n/B+,p[i])+ask(,n/B+,p[i])*v[i])%mod;
add(,n/B+,p[i],v[i]),add(,n/B+,p[i],);
}
while(m--)
{
int x,y,idx,idy;scanf("%d%d",&x,&y),x--,y--;
if(x==y){printf("%lld\n",ans);continue;}
if(x>y)swap(x,y);
idx=x/B,idy=y/B;
if(p[x]<p[y])ans=(ans+v[x]+v[y])%mod;else ans=(ans-v[x]-v[y]+*mod)%mod;
if(idx==idy)
{
for(int j=x+;j<y;j++)calc(x,y,j);
swap(p[x],p[y]),swap(v[x],v[y]);
printf("%lld\n",ans);
continue;
}
for(int j=x+;j<idx*B+B;j++)calc(x,y,j);
for(int j=idy*B;j<y;j++)calc(x,y,j);
for(int j=idx+;j<idy;j++)
{
ans=(ans-*ask(,j,p[x])+ask(,j,n)-(*ask(,j,p[x])-B+mod)*v[x]%mod+mod)%mod;
ans=(ans+*ask(,j,p[y])-ask(,j,n)+(*ask(,j,p[y])-B+mod)*v[y]%mod+mod)%mod;
}
add(,idx,p[x],-v[x]),add(,idy,p[y],-v[y]),add(,idx,p[x],-),add(,idy,p[y],-);
swap(p[x],p[y]),swap(v[x],v[y]);
add(,idx,p[x],v[x]),add(,idy,p[y],v[y]),add(,idx,p[x],),add(,idy,p[y],);
printf("%lld\n",ans);
}
}

最新文章

  1. tyvj1089 smrtfun
  2. httpclient4 文档翻译
  3. logback文章推荐
  4. [英] 推荐 15 个 jQuery 选择框插件
  5. @media 手机与IPAD与PC
  6. 基础学习day05---面向对象一类,对象、封装
  7. motto4
  8. 用script实现内容显示,并使用json传输数据
  9. leetcode第一刷_Interleaving String
  10. Unity3D 回合制 网上源码 目前还在研究构思
  11. C++学习(三)入门篇——函数
  12. CodeForces - 853A Planning (优先队列,贪心)
  13. position:absolute 的深入探讨
  14. R语言与格式、日期格式、格式转化
  15. Populating Next Right Pointers in Each Node(I and II)
  16. Excel自定义公式,类似VLOOKUP的查询
  17. SpringBoot配置mybatis
  18. 从 RAID 到 Hadoop Hdfs 『大数据存储的进化史』
  19. python is和==的区别
  20. 单机安装ELK

热门文章

  1. [题解] CF622F The Sum of the k-th Powers
  2. ArchLinux安装Gnome桌面
  3. Aspectj切入点语法定义
  4. c++ 字母排序
  5. java 的二分算法
  6. vector删除指定元素
  7. chown virtualbox
  8. viewer.js插件简单使用说明
  9. python Mysql数据库连接池组件封装(转载)
  10. Vundle安装及使用