一道比较傻的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动态逆序对的更多相关文章

  1. BZOJ3295 动态逆序对(树状数组套线段树)

    [Cqoi2011]动态逆序对 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 6058  Solved: 2117[Submit][Status][D ...

  2. bzoj3295 动态逆序对

    Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计 ...

  3. 【BZOJ3295】动态逆序对(线段树,树状数组)

    [BZOJ3295]动态逆序对(线段树,树状数组) 题面 Description 对于序列A,它的逆序对数定义为满足iAj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的 ...

  4. 【BZOJ3295】[Cqoi2011]动态逆序对 cdq分治

    [BZOJ3295][Cqoi2011]动态逆序对 Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依 ...

  5. bzoj3295 [Cqoi2011]动态逆序对 cdq+树状数组

    [bzoj3295][Cqoi2011]动态逆序对 2014年6月17日4,7954 Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数. ...

  6. bzoj3295 洛谷P3157、1393 动态逆序对——树套树

    题目:bzoj3295 https://www.lydsy.com/JudgeOnline/problem.php?id=3295 洛谷 P3157(同一道题) https://www.luogu.o ...

  7. 【题解】动态逆序对 [CQOI2011] [P3157] [BZOJ3295] [P1393]

    [题解]动态逆序对 [CQOI2011] [P3157] [BZOJ3295] [P1393] 水一水QAQ 题目链接: \([P3157]\) \([BZOJ3295]\) [题目描述] 对于一个序 ...

  8. [bzoj3295][Cqoi2011]动态逆序对_主席树

    动态逆序对 bzoj-3295 Cqoi-2011 题目大意:题目链接. 注释:略. 想法:直接建立主席树. 由于是一个一个删除,所以我们先拿建立好的root[n]的权值线段树先把总逆序对求出来,接着 ...

  9. bzoj3295[Cqoi2011]动态逆序对 树套树

    3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 5987  Solved: 2080[Submit][Sta ...

随机推荐

  1. SPOJ375 Query on a tree(树链剖分)

    传送门 题意 给出一棵树,每条边都有权值,有两种操作: 把第p条边的权值改为x 询问x,y路径上的权值最大的边 code #include<cstdio> #include<algo ...

  2. CodeForces 570E DP Pig and Palindromes

    题意:给出一个n行m列的字符矩阵,从左上角走到右下角,每次只能往右或者往下走,求一共有多少种走法能得到回文串. 分析: 可以从两头开始考虑,每次只走一样字符的格子,这样得到的两个字符串拼起来之后就是一 ...

  3. 线程中更新ui方法汇总

    一.为何写作此文   你是不是经常看到很多书籍中说:不能在子线程中操作ui,不然会报错.你是不是也遇到了如下的疑惑(见下面的代码): @Override protected void onCreate ...

  4. Freemarker的循环通过assign指令引入计数变量

    这里是一个jeecms框架的前台的一个内容列表集,因为不是每个内容子项符合要求,而且需要统计符合要求的子项个数,仿照java的for循环,需要在循环前声明一个计数变量,这就需要使用Freemaker的 ...

  5. day19-IO多路复用

    1.I/O多路复用指:通过一种机制,可监听多个描述符(soket对象)(文件句柄),一旦某个描述符发送编号(一般指读就绪或写就绪),能够通知程序进行相应的读写操作. 2.I/O多路复用方式:selec ...

  6. 【bzoj1965】 [Ahoi2005]SHUFFLE 洗牌 欧拉定理

    题目描述 为了表彰小联为Samuel星球的探险所做出的贡献,小联被邀请参加Samuel星球近距离载人探险活动. 由于Samuel星球相当遥远,科学家们要在飞船中度过相当长的一段时间,小联提议用扑克牌打 ...

  7. 【bzoj4310】跳蚤 后缀数组+二分

    题目描述 很久很久以前,森林里住着一群跳蚤.一天,跳蚤国王得到了一个神秘的字符串,它想进行研究. 首先,他会把串分成不超过 k 个子串,然后对于每个子串 S,他会从S的所有子串中选择字典序最大的那一个 ...

  8. 刷题总结——分糖(ssoj 容斥原理+逆元+快速幂+组合数求插板)

    题目: 题目描述 有 N 个(相同的)糖果,M 个(不同的)小朋友.M 和 N 满足:1≤M≤N≤100000(105).要求:1.每个小朋友都至少有一个糖果.2.不存在正整数 X(X>=2), ...

  9. java面试题之happens before原则

    JSR-133使用happens-before的概念来指定两个操作之间的执行顺序.由于这两个操作可以在一个线程内,也可以在不同线程之间.因此,JMM可以通过happens-before关系向程序员提供 ...

  10. (超详细)使用git命令行将本地仓库代码上传到github或gitlab远程仓库

    (超详细)使用git命令行将本地仓库代码上传到github或gitlab远程仓库 本地创建了一个 xcode 工程项目,现通过 命令行 将该项目上传到 github 或者 gitlab 远程仓库,具体 ...