Codeforece E. Anton and Permutation
主席树算贡献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相关推荐
- CF785E Anton and Permutation
CF785E Anton and Permutation 题意: 对于一个长度为 n 的序列进行 k 次操作,每次操作都是交换序列中的某两个数.对于每一个操作,回答当前序列中有多少个逆序对. 1< ...
- CodeForces 785E Anton and Permutation 分块
题意: 有一个\(1 \sim n\)的排列\(A\),有\(q\)个询问: 交换任意两个元素的位置,求交换之后排列的逆序数 分析: 像这种不太容易用线段树,树状数组维护的可以考虑分块 每\(\sqr ...
- 分块详解(优雅的暴力)
作者: hsez_yyh 链接: https://blog.csdn.net/yyh_getAC/article/details/126823013 来源:湖北省黄石二中信 ...
- 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 ...
- Codeforces 584E. Anton and Ira (排列好题)
大致题意: n <= 2000,有一1-n的排列p和s,对pi和pj交换产生的代价是 | i - j | , 问最少需要多少代价使,排列p变成排列s,输出解 思路: 可以先把s映射成1...n的 ...
- codeforces 324# E. Anton and Ira (暴力枚举+贪心)
题目:http://codeforces.com/contest/584/problem/E 题意:给定两个排列p1和p2.可以交换p1中的两个元素p1[i],p1[j],花费为|i-j|,求最小的话 ...
- 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 ...
- 【C++】C++11 STL算法(七):排列操作(Permutation operations)、数值操作(Numeric operations)
排列操作(Permutation operations) 一.is_permutation 1.原型: template< class ForwardIt1, class ForwardIt2 ...
- LeetCode 76. Minimum Window Substring / 567. Permutation in String
76. Minimum Window Substring 典型Sliding Window的问题,维护一个区间,当区间满足要求则进行比较选择较小的字串,重新修改start位置. 思路虽然不难,但是如何 ...
最新文章
- python sched_python事件调度库sched
- mysql安装教程 没配置_MySQL安装和配置详细教程
- 开发中为什么使用线程池的原因
- 安卓手机浏览器_chrome浏览器插件安卓下载-chrome apk手机版下载v4.8.2安卓版
- C# WebBrowser 设置代理完全解决方案
- 项目管理excel_项目管理甘特图是什么?怎么做才能更高效?(EXCEL制作甘特图详细步骤)...
- bzoj 3552: 最右非零的数 hduoj 1066: Last non-zero Digit in N!(求N!的最后一个非0位)
- 操作系统中涉及的各种调度算法
- linux中文语音合成,Linux系统下高质量(微软)中、英文语音合成TTS的安装
- 免费画图软件推荐 - draw.io
- SQL Server活动监视器
- ibm服务器安装ghostxp系统,IBM ThinkPad X61s安装WIN XP系统
- mysql begin end 定界符_mysql存储过程BEGIN END复合语句用法示例
- ListView组件的应用
- 网易2017春招笔试——集合
- Java String intern()方法
- MySQL——创建视图的注意事项
- 配电房远程监控运维系统
- Windows10设置自动重启或定时重启的方法
- Everything.exe命令行激发窗口查询
热门文章
- java set集合与List集合练习
- quartz 两次执行问题
- Oracle数据库备份dmp文件,使用cmd命令导入导出步骤,以及忘记Oracle密码
- Spcomm使用属性及用法详解
- hexo+github+hexo-theme-matery搭建个人免费博客
- TypeScript与React中如何使用ref
- 【博客项目】—cookie和session(七)
- 【博客项目】—登录验证功能实现( 五)
- JavaScript学习(四十五)—练习题
- authorization 传 就跨域_headers中添加允许token,客户端跨域请求问题