主席树算贡献l,r中交换位置,算出>=rank(h) 和 <=rank(h)  a[l],a[r] 先不统计 a[l]比a[r]大的话交换后ans-1,a[l]比a[r]小的话交换后ans-1,ans+<r的,->r的 ans-<l的,+>l的,区间比k大的数量或者区间第k大等类似的可以用第二类主席树弄
#include <cstdio>
#include <memory>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <vector>
#include <cassert>
#include <string>
#include <ctime>
#include <map>
#include <queue>
#include <algorithm>
#include <iostream>
#include <cassert>
#include <set>
using namespace std;
#define REP(i,n) for(int i=0;i<n;i++)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define req(i,a,b) for(int i=a;i>=b;i--)
#define rp(i,a) for(int i=head[a];i+1;i=edge[i].next)
#define cl(a,b) memset(a,b,sizeof a);
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mod 10007
const int inf = ~0u >> 2;
const ll INF = (1LL << 62) - 1;
double eps = 1e-12;
const int N = 500005 + 5;
const int M = 200005;int n, m, d;
int a[500005];
int rnk[N];
int root[N];
int croot[N];
int sz = 0, tot = 0;
void insert(int &num, int val, int k, int l, int r);
struct Node {int sum;int ch[2];
}T[30500010];
void insert(int &num, int val, int k, int l, int r, int flag) {if (flag == 0 || num == 0) {T[++sz] = T[num]; num = sz;}T[num].sum += val;if (l == r) {return;}int m = (l + r) >> 1;if (k <= m) {insert(T[num].ch[0], val, k, l, m, flag);}else {insert(T[num].ch[1], val, k, m + 1, r, flag);}
}
int query(int i, int j, int k, int l, int r) {if (k > T[j].sum - T[i].sum)k = T[i].sum - T[i].sum;if (l == r)return l;int m = (l + r) >> 1;if (k <= T[T[j].ch[0]].sum - T[T[i].ch[0]].sum)return query(T[i].ch[0], T[j].ch[0], k, l, m);elsereturn query(T[i].ch[1], T[j].ch[1], k - (T[T[j].ch[0]].sum - T[T[i].ch[0]].sum), m + 1, r);
}
void add(int x, int num, int d) {while (x <= tot) {insert(croot[x], d, num, 1, tot, 1);x += x&-x;}
}
struct Pack {vector<int> v;Pack() {}Pack(int x) { v.push_back(x); }void operator +=(int x) {v.push_back(x);}operator ll()const {//得到左孩子和ll ret = 0;for (int i = 0; i<v.size(); i++)ret += T[T[v[i]].ch[0]].sum;return ret;}void lt() {for (int i = 0; i < v.size(); i++)v[i] = T[v[i]].ch[0];}void rt() {for (int i = 0; i < v.size(); i++)v[i] = T[v[i]].ch[1];}
};
Pack sum(int x, int k) {Pack ret;while (x>0) {ret += croot[x];x -= x&-x;}return ret;
}
ll binSearch(int l, int r, int k) {Pack treesl = sum(l,0);Pack treesr = sum(r,0);Pack presl = Pack(root[l]);Pack presr = Pack(root[r]);int xl = 1, xr = tot;ll ret = 0;int rtl = root[l];int rtr = root[r];while (xl < xr) {int mid = (xl + xr) >> 1;ll t = treesr - treesl + presr - presl;if (mid <= k) {ret += t;treesr.rt(); treesl.rt(); presr.rt(); presl.rt();//ret += T[T[rtr].ch[0]].sum - T[T[rtl].ch[0]].sum;xl = mid+1;if (mid == k) {ret--;break;}}else {treesr.lt(); treesl.lt(); presr.lt(); presl.lt();xr = mid;}}return ret;
}
struct Seg {int l, r, h, x;
}q[M];
int val[N];
int cnt = 0;
int Hash(int x) {return lower_bound(val, val + tot, x) - val + 1;
}
int b[N];
int main() {//for (int i = 0; i <= sz; i++)T[i] = T[0];cnt = 0;sz = 0;tot = 0;scanf("%d%d", &n, &m);for (int i = 1; i <= n; i++) {a[i] = i;b[i] = i;val[cnt++] = a[i];}for (int i = 0; i < m; i++) {int x, y;scanf("%d%d", &x, &y);if (x > y)swap(x, y);q[i * 4].l = x;q[i * 4].r = y;q[i * 4].h = b[y];q[i * 4].x = -1;q[i * 4 + 1].l = x;q[i * 4 + 1].r = y;q[i * 4 + 1].h = b[x];q[i * 4 + 1].x = -2;q[i*4+2].x = x;q[i*4+2].h = b[y];//val[cnt++] = b[y];q[i*4+2].l = -inf;q[i * 4+3].x = y;q[i * 4+3].h = b[x];//val[cnt++] = b[x];q[i * 4+3].l = -inf;swap(b[x], b[y]);/*if (l<1 || r>n || l>r || h<1 || h>r - l + 1)assert(false);*/}sort(val, val + cnt);rnk[0] = ++tot;for (int i = 1; i < cnt; i++) {if (val[i] != val[i - 1])rnk[i] = ++tot;elsernk[i] = tot;}for (int i = 0; i <= tot; i++)croot[i] = 0;unique(val, val + cnt);root[0] = 0;for (int i = 1; i <= n; i++) {root[i] = root[i - 1];insert(root[i], 1, Hash(a[i]), 1, tot, 0);}ll ans = 0;for (int i = 0; i < 4*m; i++) {if (q[i].l != -inf) {if (q[i].x == -1) {if (q[i].l != q[i].r) {ll tmp = binSearch(q[i].l - 1, q[i].r, Hash(q[i].h));if (a[q[i].l] < a[q[i].r])tmp--;ans += tmp;ans -= max(0LL, (q[i].r - q[i].l - tmp - 1));}//printf("%d\n", val[binSearch(q[i].l - 1, q[i].r, q[i].h) - 1]);}if (q[i].x == -2) {if (q[i].l != q[i].r) {ll tmp = binSearch(q[i].l - 1, q[i].r, Hash(q[i].h));if (a[q[i].l] > a[q[i].r])tmp--;ans -= tmp;ans += max(0LL, (q[i].r - q[i].l - tmp - 1));}if (a[q[i].l] > a[q[i].r])ans--;else if(a[q[i].l]<a[q[i].r])ans++;cout << ans << endl;}}else {add(q[i].x, Hash(a[q[i].x]), -1);a[q[i].x] = q[i].h;add(q[i].x, Hash(q[i].h), 1);}}//cout << ans << endl;/*for (int i = 1; i <= tot; i++)croot[i] = 0, val[i] = 0, a[i] = 0;*/return 0;
}

转载于:https://www.cnblogs.com/HaibaraAi/p/6561528.html

Codeforece E. Anton and Permutation相关推荐

  1. CF785E Anton and Permutation

    CF785E Anton and Permutation 题意: 对于一个长度为 n 的序列进行 k 次操作,每次操作都是交换序列中的某两个数.对于每一个操作,回答当前序列中有多少个逆序对. 1< ...

  2. CodeForces 785E Anton and Permutation 分块

    题意: 有一个\(1 \sim n\)的排列\(A\),有\(q\)个询问: 交换任意两个元素的位置,求交换之后排列的逆序数 分析: 像这种不太容易用线段树,树状数组维护的可以考虑分块 每\(\sqr ...

  3. 分块详解(优雅的暴力)

    作者: hsez_yyh 链接: ​​​​​​​​​​​​​​https://blog.csdn.net/yyh_getAC/article/details/126823013 来源:湖北省黄石二中信 ...

  4. Codeforces Round #324 (Div. 2) E. Anton and Ira 贪心

    E. Anton and Ira Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/584/probl ...

  5. Codeforces 584E. Anton and Ira (排列好题)

    大致题意: n <= 2000,有一1-n的排列p和s,对pi和pj交换产生的代价是 | i - j | , 问最少需要多少代价使,排列p变成排列s,输出解 思路: 可以先把s映射成1...n的 ...

  6. codeforces 324# E. Anton and Ira (暴力枚举+贪心)

    题目:http://codeforces.com/contest/584/problem/E 题意:给定两个排列p1和p2.可以交换p1中的两个元素p1[i],p1[j],花费为|i-j|,求最小的话 ...

  7. codeforces#324(div2) E. Anton and Ira 贪心

    codeforces#324(div2) E. Anton and Ira  贪心 E. Anton and Ira time limit per test 1 second memory limit ...

  8. 【C++】C++11 STL算法(七):排列操作(Permutation operations)、数值操作(Numeric operations)

    排列操作(Permutation operations) 一.is_permutation 1.原型: template< class ForwardIt1, class ForwardIt2 ...

  9. LeetCode 76. Minimum Window Substring / 567. Permutation in String

    76. Minimum Window Substring 典型Sliding Window的问题,维护一个区间,当区间满足要求则进行比较选择较小的字串,重新修改start位置. 思路虽然不难,但是如何 ...

最新文章

  1. python sched_python事件调度库sched
  2. mysql安装教程 没配置_MySQL安装和配置详细教程
  3. 开发中为什么使用线程池的原因
  4. 安卓手机浏览器_chrome浏览器插件安卓下载-chrome apk手机版下载v4.8.2安卓版
  5. C# WebBrowser 设置代理完全解决方案
  6. 项目管理excel_项目管理甘特图是什么?怎么做才能更高效?(EXCEL制作甘特图详细步骤)...
  7. bzoj 3552: 最右非零的数 hduoj 1066: Last non-zero Digit in N!(求N!的最后一个非0位)
  8. 操作系统中涉及的各种调度算法
  9. linux中文语音合成,Linux系统下高质量(微软)中、英文语音合成TTS的安装
  10. 免费画图软件推荐 - draw.io
  11. SQL Server活动监视器
  12. ibm服务器安装ghostxp系统,IBM ThinkPad X61s安装WIN XP系统
  13. mysql begin end 定界符_mysql存储过程BEGIN END复合语句用法示例
  14. ListView组件的应用
  15. 网易2017春招笔试——集合
  16. Java String intern()方法
  17. MySQL——创建视图的注意事项
  18. 配电房远程监控运维系统
  19. Windows10设置自动重启或定时重启的方法
  20. Everything.exe命令行激发窗口查询

热门文章

  1. java set集合与List集合练习
  2. quartz 两次执行问题
  3. Oracle数据库备份dmp文件,使用cmd命令导入导出步骤,以及忘记Oracle密码
  4. Spcomm使用属性及用法详解
  5. hexo+github+hexo-theme-matery搭建个人免费博客
  6. TypeScript与React中如何使用ref
  7. 【博客项目】—cookie和session(七)
  8. 【博客项目】—登录验证功能实现( 五)
  9. JavaScript学习(四十五)—练习题
  10. authorization 传 就跨域_headers中添加允许token,客户端跨域请求问题