题意很明确,也非常经典:

一个支持查询 区间中比k大的数的个数 并且支持单点修改的序列

——因为题意可以转化为:查询这两个数中比后者大的个数、比后者小的个数、比前者大的个数、比前者小的个数(根据这4个就能算出增加/减少了多少对逆序对)并且把两个数修改掉

于是就出现了

——来自百度

一个二分就能解决套个卵蛋woc身为一个蒟蒻,表示没有一个写得出的

于是我就想了一个好写(Rank100+几乎T掉)的方法:

首先复制一份原数据,把一份分块,并且保证每一块中的单调(也就是调用sqrt(n)次排序)

然后在查询时对于单块暴力处理,对于整块二分查找;修改时冒泡(呵呵,不要吐槽)

——一听复杂度就好大,那就算一算吧

首先要排序O(sqrt(n)*sqrt(n)*lg sqrt(n))              //sqrt(n)次的排序,每次nlgn(这里的n为原题的sqrt(n))

其次是查询O(m*(sqrt(n)+sqrt(n)*lg sqrt(n)))      //总共有m次,每次零散的有sqrt(n)个,整块的有sqrt(n)块,每块费时lg sqrt(n)

最后是修改O(m*(sqrt(n)+sqrt(n)))                       //冒个泡应该不用解释,每次收尾都需要冒一遍,一遍最多sqrt(n)次移动

然后愉快地堆起来变成预处理O(n*lg sqrt(n))主体O(m*sqrt(n)*lgn)

介于数据弱(如果按套来套去的结构算好像还可以加大一点数据,但是蒟蒻表示受不了,这么个简单思路我调了一下午),我还是过掉了

代码风格属于臭婆娘的擦脚布,不喜勿喷

 #include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
int n,m,x,y,N;
int a[],b[];//未排序数据和已排序数据
int l[],r[];//分块两端
//处理重复数据真TM的累,find和Find带_的是找小于给定关键字的数的个数的,不带的是找大于的个数的
int Find(int o,int x)//在一块中二分查找x
{
int L=l[o],R=r[o];
while(L<R-)
{
int mid=(L+R)/;
if(b[mid]<=x)//这边一开始缺个等号导致我调一下午
L=mid;
else
R=mid;
}
if(b[R]<=x)
return r[o]-R;
else
if(x<b[L])
return r[o]-L+;
else
return r[o]-L;
}
int find(int x,int y,int z)//查询,分成三段分别求解
{
int sum=;
for(int i=;i<=N;i++)
if((x<=l[i])&&(r[i]<=y))
sum+=Find(i,z);
else
if((x>=l[i])&&(y<=r[i]))
{
for(int j=x;j<=y;j++)
sum+=a[j]>z;
return sum;
}
else
if(x>=l[i] && x<=r[i])
for(int j=x;j<=r[i];j++)
sum+=a[j]>z;
else
if(l[i]<=y && y<=r[i])
{
for(int j=l[i];j<=y;j++)
sum+=a[j]>z;
return sum;
}
return sum;
}
int _Find(int o,int x)//在一块中二分查找x
{
int L=l[o],R=r[o];
while(L<R-)
{
int mid=(L+R)/;
if(b[mid]<x)//这边不能有等号,非常神奇,建议想一想为什么
L=mid;
else
R=mid;
}
if(b[R]<x)
return R-l[o]+;
else
if(x<=b[L])
return L-l[o];
else
return R-l[o];
}
int _find(int x,int y,int z)//查询,分成三段分别求解
{
int sum=;
for(int i=;i<=N;i++)
if((x<=l[i])&&(r[i]<=y))
sum+=_Find(i,z);
else
if((x>=l[i])&&(y<=r[i]))
{
for(int j=x;j<=y;j++)
sum+=a[j]<z;
return sum;
}
else
if(x>=l[i] && x<=r[i])
for(int j=x;j<=r[i];j++)
sum+=a[j]<z;
else
if(l[i]<=y && y<=r[i])
{
for(int j=l[i];j<=y;j++)
sum+=a[j]<z;
return sum;
}
return sum;
}
void change(int x,int y)//把位于x的数改成y,冒个泡
{
int i,j;
for(i=;r[i]<x;i++);
for(j=l[i];b[j]!=a[x];j++);
b[j]=y;
while((j<r[i])&&(b[j]>b[j+]))
{
swap(b[j],b[j+]);
j++;
}
while((j>l[i])&&(b[j]<b[j-]))
{
swap(b[j],b[j-]);
j--;
}
a[x]=y;
}
int init()//预处理,分块+排序
{
int sq=(int)sqrt(n);
for(int i=;i<=sq;i++)
{
l[i]=sq*(i-)+;
r[i]=sq*i;
}
if(sq*sq<n)
{
l[sq+]=sq*sq+;
r[++sq]=n;
}
memcpy(b,a,sizeof(a));
for(int i=;i<=sq;i++)
sort(b+l[i],b+r[i]+);
return sq;
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
N=init();
int ans=;
for(int i=;i<n;i++)
ans+=_find(i+,n,a[i]);
printf("%d\n",ans);
scanf("%d",&m);
for(int i=;i<=m;i++)
{
scanf("%d%d",&x,&y);
if(x>y)
swap(x,y);
ans-=find(x,y-,a[y]);
ans+=_find(x,y-,a[y]);
if(y-x>)
{
ans+=find(x+,y-,a[x]);
ans-=_find(x+,y-,a[x]);
}
printf("%d\n",ans);
int t=a[x];
change(x,a[y]);
change(y,t);
}
return ;
}

据说一个函数不能太长,否则难看,于是就瞎写成了这副德行%还是不习惯啊

bzoj2141排队(辣鸡但是好写的方法)的更多相关文章

  1. 7.29 NOIP模拟测试10 辣鸡(ljh)+模板(ac)+大佬(kat)

    T1 辣鸡(ljh) 就是一道分类讨论的暴搜,外加一丢丢的减枝,然而我挂了,为啥呢,分类讨论变量名打错,大于小于号打反,能对才怪,写了sort为了调试就注释了,后来忘了解开,小减枝也没打.但是这道题做 ...

  2. JVM 辣鸡回收

    垃圾回收算法 标记清除法 先标记出需要回收的对象,然后一次性回收.缺点:会产生内存碎片,并且效率也不高. 标记压缩法 先标记出需要回收的对象,然后让存活对象向一端移动,移动的过程中进行回收辣鸡.避免了 ...

  3. [CSP-S模拟测试]:辣鸡(ljh) (暴力)

    题目描述 辣鸡$ljh\ NOI$之后就退役了,然后就滚去学文化课了.然而在上化学课的时候,数学和化学都不好的$ljh$却被一道简单题难住了,受到了大佬的嘲笑.题目描述是这样的:在一个二维平面上有一层 ...

  4. noip模拟6[辣鸡·模板·大佬·宝藏]

    这怕不是学长出的题吧 这题就很迷 这第一题吧,正解竟然是O(n2)的,我这是快气死了,考场上一直觉得aaaaa n2过不了过不了, 我就去枚举边了,然后调了两个小时,愣是没调出来,然后交了个暴力,就走 ...

  5. NOIP模拟测试10「大佬·辣鸡·模板」

    大佬 显然假期望 我奇思妙想出了一个式子$f[i]=f[i-1]+\sum\limits_{j=1}^{j<=m} C_{k \times j}^{k}\times w[j]$ 然后一想不对得容 ...

  6. [改善Java代码]不推荐覆写start方法

    多线程比较简单的方式是继承Thread类,然后覆写run()方法,在客户端程序中通过调用对象的start方法即可启动一个线程,这个是多线程程序的标准写法. 错误代码: public class Cli ...

  7. [改善Java代码]覆写equals方法必须覆写hashCode方法

    覆写equals方法必须覆写hashCode方法,这条规则基本上每个Javaer都知道,这也是JDK API上反复说明的,不过为什么要这样做呢?这两个方法之间有什么关系呢?本建议就来解释该问题,我们先 ...

  8. [改善Java代码]覆写equals方法时不要识别不出自己

    建议45: 覆写equals方法时不要识别不出自己 我们在写一个JavaBean时,经常会覆写equals方法,其目的是根据业务规则判断两个对象是否相等,比如我们写一个Person类,然后根据姓名判断 ...

  9. [改善Java代码]推荐覆写toString方法

    建议49: 推荐覆写toString方法 为什么要覆写toString方法,这个问题很简单,因为Java提供的默认toString方法不友好,打印出来看不懂,不覆写不行,看这样一段代码: public ...

随机推荐

  1. Mysql导入数据命令

    转自:http://blog.sina.com.cn/s/blog_610997850100mwv8.html 今天碰到个问题要用phpmyadmin导入1G的数据,但是在怎么都导入不了,用命令行就可 ...

  2. ubuntu12.04server下red5-1.0.0RC1的部署

    一.搭建环境 Linux版本:ubuntu12.04sever  64位 Java  版本:Java 1.7(jdk+jre) Red5 版本:red5-1.0.0-RC1 二.安装JDK 下载jdk ...

  3. UIScrollView的代理(delegate)

    很多时候,我们想在UIScrollView正在滚动 或 滚动到某个位置 或者 停止滚动 时做一些特定的操作 要想完成上述功能,前提条件就是能够监听到UIScrollView的整个滚动过程 当UIScr ...

  4. css浏览器兼容问题

    https://www.douban.com/group/topic/4629864/

  5. 最短JavaScript判断是否为IE6、IE的方法

    常用的 JavaScript 检测浏览器为 IE 是哪个版本的代码,包括是否是最人极端厌恶的 ie6 识别与检测. var isIE=!!window.ActiveXObject; var isIE6 ...

  6. URL传递中文字符,特殊危险字符的解决方案(仅供参考)urldecode、base64_encode

    很多时候,我们需要在url中传递中文字符或是其它的html等特殊字符,似乎总会有各种乱,不同的浏览器对他们的编码又不一样, 对于中文,一般的做法是: 把这些文本字符串传给url之前,先进行urlenc ...

  7. 混合开发 webview 中file 控件 点击后无反应解决方法

    最近在做个项目 ,需要 使用 file 控件上传 图片到服务器 ,在手机浏览器中 可以正常选择照片,但是放到 android 应用中的webview中,file 控件点击后就没有反应. 百度了一番后, ...

  8. 1.3为WebApi创建帮助文档

    当你创建一个网络 API 时,它很有用来创建一个帮助页,以便其他开发人员将知道如何调用您的 API.您可以创建的所有文档手动,但它是自动生成尽可能多地更好. 为了简化这一任务,ASP.NET Web ...

  9. SSI指令

    1.SSI定义 SSI是英文Server Side Includes的缩写, 即“服务器端包含”或“服务器端嵌入”技术. SSI在HTML文件中,可以通过注释行调用的命令或指针,是一种基于服务器端的网 ...

  10. zTree学习

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...