BZOJ3295动态逆序对
一道比较傻的CDQ分治
CDQ: 主要用于解决三位偏序的问题
#include<cstdio>
#include<cctype>
#include<algorithm>
#include<cstring>
using namespace std;
inline long long read()
{
long long x = 0, flag = 1;
char c;
while(! isgraph(c = getchar()))
if(c == '-')
flag *= - 1;
while(isgraph(c))
x = x * 10 + c - '0', c = getchar();
return x * flag;
}
void println(long long x)
{
if(x < 0)
putchar('-'), x *= - 1;
if(x == 0)
putchar('0');
long long ans[10 + (1 << 4)], top = 0;
while(x)
ans[top ++] = x % 10, x /= 10;
for(; top; top --)
putchar(ans[top - 1] + '0');
putchar('\n');
}
const long long MAXN = (long long)1e5 + (1 << 5);
struct spot
{
long long t, pos, w;
spot(){}
spot(long long t, long long pos, long long w): t(t), pos(pos), w(w){}
}a[MAXN], b[MAXN];
long long pos[MAXN];
long long operator <(spot x, spot y)
{
if(x.t != y.t)
return x.t < y.t;
return x.pos < y.pos;
}
long long n;
long long ans[MAXN];
long long tree[MAXN];
void modify(long long u, long long delta)
{
while(u <= n)
tree[u] += delta, u += (u & (-u));
}
long long query(long long u)
{
long long ret = 0;
while(u)
ret += tree[u], u -= (u & (- u));
return ret;
}
long long cmp(spot x, spot y)
{
return x.pos < y.pos;
}
void CDQ(long long L, long long R)
{
if(L + 1 >= R)
return;
long long top = 0;
long long mid = (L + R) >> 1;
for(long long i = L; i < mid; i ++)
b[top] = a[i], b[top ++].t = - 1;
for(long long i = mid; i < R; i ++)
b[top ++] = a[i];
sort(b, b + top, cmp);
long long cnt = 0;
for(long long i = 0; i < top; i ++)
{
if(b[i].t == - 1)
modify(b[i].w, 1), cnt ++;
else
ans[b[i].t] += query(n) - query(b[i].w);
}
for(long long i = 0; i < top; i ++)
if(b[i].t == - 1)
modify(b[i].w, - 1);
CDQ(L, mid);
CDQ(mid, R);
}
long long cmp2(spot x, spot y)
{
if(x.t != y.t)
return x.t < y.t;
return x.pos > y.pos;
}
long long cmp1(spot x, spot y)
{
return x.pos > y.pos;
}
void CDQ1(long long L, long long R)
{
if(L + 1 >= R)
return;
long long top = 0;
long long mid = (L + R) >> 1;
for(long long i = L; i < mid; i ++)
b[top] = a[i], b[top ++].t = - 1;
for(long long i = mid; i < R; i ++)
b[top ++] = a[i];
sort(b, b + top, cmp1);
long long cnt = 0;
for(long long i = 0; i < top; i ++)
{
if(b[i].t == - 1)
modify(b[i].w, 1), cnt ++;
else
ans[b[i].t] += query(b[i].w);
}
for(long long i = 0; i < top; i ++)
if(b[i].t == - 1)
modify(b[i].w, - 1);
CDQ1(L, mid);
CDQ1(mid, R);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("BZOJ3295.in", "r", stdin);
freopen("BZOJ3295.out", "w", stdout);
#endif
n = read();
long long m = read();
for(long long i = 0; i < n; i ++)
a[i].pos = i, a[i].w = read(), a[i].t = n - m, pos[a[i].w] = i;
for(long long i = 0; i < m; i ++)
a[pos[read()]].t = n - i;
sort(a, a + n);
memset(ans, 0, sizeof(ans));
memset(tree, 0, sizeof(tree));
CDQ(0, n);
sort(a, a + n, cmp2);
CDQ1(0, n);
for(long long i = n - m + 2; i <= n; i ++)
ans[i] += ans[i - 1];
for(long long i = n; i > n - m; i --)
println(ans[i]);
}
顺便, 承蒙YAY大神的指导, 学会了一个可以用来出数据的函数random_shuffle(int&, int&), 用于随机打乱区间中的元素. 附上对拍代码
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<cctype>
#include<algorithm>
using namespace std;
inline int read()
{
int x = 0, flag = 1;
char c;
while(! isgraph(c = getchar()))
if(c == '-')
flag *= - 1;
while(isgraph(c))
x = x * 10 + c - '0', c = getchar();
return x * flag;
}
void println(int x)
{
if(x < 0)
putchar('-'), x *= - 1;
if(x == 0)
putchar('0');
int ans[10 + (1 << 4)], top = 0;
while(x)
ans[top ++] = x % 10, x /= 10;
for(; top; top --)
putchar(ans[top - 1] + '0');
putchar('\n');
}
const int maxn=1e5+10;
int a[maxn];
int main() {
freopen("bzoj3295.in","w",stdout);
srand(time(0));
int n=100000;
printf("%d %d\n",n,n);
for (int i=1;i<=n;++i) a[i]=i;
random_shuffle(a+1,a+n+1);
for (int i=1;i<=n;++i) printf("%d ",a[i]);
puts("");
random_shuffle(a+1,a+n+1);
for (int i=1;i<=n;++i) printf("%d ",a[i]);
puts("");
}
对拍用的BAT
@echo off
:loop
mkd
BZOJ3295
ni
fc BZOJ3295.out ni.out
if not errorlevel 1 goto loop
pause
BZOJ3295动态逆序对的更多相关文章
- BZOJ3295 动态逆序对(树状数组套线段树)
[Cqoi2011]动态逆序对 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 6058 Solved: 2117[Submit][Status][D ...
- bzoj3295 动态逆序对
Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计 ...
- 【BZOJ3295】动态逆序对(线段树,树状数组)
[BZOJ3295]动态逆序对(线段树,树状数组) 题面 Description 对于序列A,它的逆序对数定义为满足iAj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的 ...
- 【BZOJ3295】[Cqoi2011]动态逆序对 cdq分治
[BZOJ3295][Cqoi2011]动态逆序对 Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依 ...
- bzoj3295 [Cqoi2011]动态逆序对 cdq+树状数组
[bzoj3295][Cqoi2011]动态逆序对 2014年6月17日4,7954 Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数. ...
- bzoj3295 洛谷P3157、1393 动态逆序对——树套树
题目:bzoj3295 https://www.lydsy.com/JudgeOnline/problem.php?id=3295 洛谷 P3157(同一道题) https://www.luogu.o ...
- 【题解】动态逆序对 [CQOI2011] [P3157] [BZOJ3295] [P1393]
[题解]动态逆序对 [CQOI2011] [P3157] [BZOJ3295] [P1393] 水一水QAQ 题目链接: \([P3157]\) \([BZOJ3295]\) [题目描述] 对于一个序 ...
- [bzoj3295][Cqoi2011]动态逆序对_主席树
动态逆序对 bzoj-3295 Cqoi-2011 题目大意:题目链接. 注释:略. 想法:直接建立主席树. 由于是一个一个删除,所以我们先拿建立好的root[n]的权值线段树先把总逆序对求出来,接着 ...
- bzoj3295[Cqoi2011]动态逆序对 树套树
3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 5987 Solved: 2080[Submit][Sta ...
随机推荐
- 彻底卸载gedit
$ sudo apt-get purge gedit gedit-plugins$ sudo apt-get autoremove
- 引用&符号详解
变量的引用 PHP 的引用允许你用两个变量来指向同一个内容. 例一: <?php $a="2010"; $b =&$a; echo $a;//这里输出:2010 ec ...
- HashMap的C++实现
#include <iostream> #include <cstring> #include <string> typedef unsigned int SIZE ...
- 04_ThreadLocal整合事务操作
文章导读: 本文主要讲解了如何在没有框架情况下如何解决Dao的事务问题, 重点理解Connection存放到WeakReference中为什么垃圾回收的时候Connection不回收 视频与源码下载: ...
- [POJ 1000] A+B Problem 经典水题 C++解题报告 JAVA解题报告
A+B Problem Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 311263 Accepted: 1713 ...
- windows系统使用的误区
1.软件不要装在c盘,影响系统运行速度. 软件c盘不会影响系统运行,会提高软件运行速度 PS:前提条件:C盘有足够的空余空间(50G以上). 大多数软件安装默认路径在C盘的原因是不知道电脑分区的情况, ...
- Leetcode 480.滑动窗口中位数
滑动窗口中位数 中位数是有序序列最中间的那个数.如果序列的大小是偶数,则没有最中间的数:此时中位数是最中间的两个数的平均数. 例如: [2,3,4],中位数是 3 [2,3],中位数是 (2 + 3) ...
- TensorFlow——小练习:feed
feed就是喂入数据 使用feed前必须要有占位符作为操作的对象,在运行操作的时候喂入数据. # _*_coding:utf-8_*_ import tensorflow as tf import n ...
- [python学习篇][书籍学习][python standrad library][内建函数]之[all,any,basestring,isinstance,bin,bool,@classmethod,@staticmethod,cmp,enumerate
Python 解释器内置了一些函数,它们总是可用的.这里将它们按字母表顺序列出. Built-in Functions abs() divmod() input() open() st ...
- C语言总结(5)
一.函数的定义: 函数是一个完成特定工作的独立程序模块,包括库函数和自定义函数.例如:scanf(),printf()为库函数,cylinder(),fact()为自定义函数. 函数定义的一般形式: ...