Yaroslav and Points

明明区间合并一下就好的东西, 为什么我会写得这么麻烦的方法啊啊啊。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ull unsigned long long using namespace std; const int N = 2e5 + ;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + ;
const double eps = 1e-;
const double PI = acos(-); vector<int> oo;
int getPos(int x) {
return lower_bound(oo.begin(), oo.end(), x) - oo.begin() + ;
}
int getPosL(int x) {
return lower_bound(oo.begin(), oo.end(), x) - oo.begin() + ;
}
int getPosR(int x) {
return upper_bound(oo.begin(), oo.end(), x) - oo.begin();
} namespace SGT {
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
LL sum[N << ], cnt[N << ];
LL lazya[N << ], lazyb[N << ], all[N << ];
inline void push(int rt) {
if(lazya[rt]) {
lazya[rt << ] += lazya[rt];
lazya[rt << | ] += lazya[rt];
all[rt << ] += cnt[rt << ] * lazya[rt];
all[rt << | ] += cnt[rt << | ] * lazya[rt];
lazya[rt] = ;
}
if(lazyb[rt]) {
lazyb[rt << ] += lazyb[rt];
lazyb[rt << | ] += lazyb[rt];
all[rt << ] += sum[rt << ] * lazyb[rt];
all[rt << | ] += sum[rt << | ] * lazyb[rt];
lazyb[rt] = ;
}
}
inline void pull(int rt) {
sum[rt] = sum[rt << ] + sum[rt << | ];
cnt[rt] = cnt[rt << ] + cnt[rt << | ];
all[rt] = all[rt << ] + all[rt << | ];
}
void modify1(int p, LL val, int l, int r, int rt) {
if(l == r) {
cnt[rt] += val;
sum[rt] += oo[l - ] * val;
if(!cnt[rt]) all[rt] = ;
return;
}
push(rt);
int mid = l + r >> ;
if(p <= mid) modify1(p, val, lson);
else modify1(p, val, rson);
pull(rt);
}
void modify2(int L, int R, LL val, int l, int r, int rt) {
if(L > R) return;
if(l >= L && r <= R) {
lazya[rt] += val;
all[rt] += val * cnt[rt];
return;
}
push(rt);
int mid = l + r >> ;
if(L <= mid) modify2(L, R, val, lson);
if(R > mid) modify2(L, R, val, rson);
pull(rt);
}
void modify3(int L, int R, LL val, int l, int r, int rt) {
if(L > R) return;
if(l >= L && r <= R) {
lazyb[rt] += val;
all[rt] += val * sum[rt];
return;
}
push(rt);
int mid = l + r >> ;
if(L <= mid) modify3(L, R, val, lson);
if(R > mid) modify3(L, R, val, rson);
pull(rt);
}
PLL query1(int L, int R, int l, int r, int rt) {
if(L > R) return mk(, );
if(l >= L && r <= R) return mk(sum[rt], cnt[rt]);
push(rt);
int mid = l + r >> ;
PLL ans = mk(, ), tmp = mk(, );
if(L <= mid) {
tmp = query1(L, R, lson);
ans.fi += tmp.fi; ans.se += tmp.se;
}
if(R > mid) {
tmp = query1(L, R, rson);
ans.fi += tmp.fi; ans.se += tmp.se;
}
return ans;
}
LL query2(int L, int R, int l, int r, int rt) {
if(L > R) return ;
if(l >= L && r <= R) return all[rt];
push(rt);
int mid = l + r >> ;
LL ans = ;
if(L <= mid) ans += query2(L, R, lson);
if(R > mid) ans += query2(L, R, rson);
return ans;
}
} int n, m, x[N], c[N];
pair<PII, int> qus[N]; int main() {
scanf("%d", &n);
for(int i = ; i <= n; i++) {
scanf("%d", &x[i]);
c[i] = x[i];
oo.push_back(x[i]);
}
scanf("%d", &m);
for(int i = ; i <= m; i++) {
scanf("%d%d%d", &qus[i].se, &qus[i].fi.fi, &qus[i].fi.se);
if(qus[i].se == ) {
c[qus[i].fi.fi] += qus[i].fi.se;
oo.push_back(c[qus[i].fi.fi]);
}
}
sort(oo.begin(), oo.end());
oo.erase(unique(oo.begin(), oo.end()), oo.end());
for(int i = ; i <= n; i++) SGT::modify1(getPos(x[i]), , , SZ(oo), );
for(int i = ; i <= n; i++) {
PLL add = SGT::query1(getPos(x[i]), SZ(oo), , SZ(oo), );
SGT::modify2(getPos(x[i]), getPos(x[i]), add.fi, , SZ(oo), );
SGT::modify3(getPos(x[i]), getPos(x[i]), -add.se, , SZ(oo), );
}
for(int i = ; i <= m; i++) {
if(qus[i].se == ) {
int p = qus[i].fi.fi, d = qus[i].fi.se;
if(d > ) {
SGT::modify1(getPos(x[p]), -, , SZ(oo), );
SGT::modify2(, getPos(x[p]) - , d, , SZ(oo), );
SGT::modify2(getPos(x[p]) + , getPos(x[p] + d) - , x[p] + d, , SZ(oo), );
SGT::modify3(getPos(x[p]) + , getPos(x[p] + d) - , -, , SZ(oo), );
x[p] += d;
SGT::modify1(getPos(x[p]), , , SZ(oo), );
PLL add = SGT::query1(getPos(x[p]), SZ(oo), , SZ(oo), );
SGT::modify2(getPos(x[p]), getPos(x[p]), add.fi, , SZ(oo), );
SGT::modify3(getPos(x[p]), getPos(x[p]), -add.se, , SZ(oo), );
} else if(d < ) {
d = -d;
SGT::modify1(getPos(x[p]), -, , SZ(oo), );
SGT::modify2(, getPos(x[p] - d) - , -d, , SZ(oo), );
SGT::modify2(getPos(x[p] - d) + , getPos(x[p]) - , -x[p], , SZ(oo), );
SGT::modify3(getPos(x[p] - d) + , getPos(x[p]) - , , , SZ(oo), );
x[p] -= d;
SGT::modify1(getPos(x[p]), , , SZ(oo), );
PLL add = SGT::query1(getPos(x[p]), SZ(oo), , SZ(oo), );
SGT::modify2(getPos(x[p]), getPos(x[p]), add.fi, , SZ(oo), );
SGT::modify3(getPos(x[p]), getPos(x[p]), -add.se, , SZ(oo), );
}
} else {
int L = qus[i].fi.fi, R = qus[i].fi.se;
L = getPosL(L); R = getPosR(R);
LL ans = SGT::query2(L, R, , SZ(oo), );
PLL tmpL = SGT::query1(L, R, , SZ(oo), );
PLL tmpR = SGT::query1(R + , SZ(oo), , SZ(oo), );
ans -= tmpL.se * tmpR.fi;
ans += tmpL.fi * tmpR.se;
printf("%lld\n", ans);
}
}
return ;
} /*
*/

Codeforces 295E Yaroslav and Points 线段树的更多相关文章

  1. Codeforces Beta Round #19D(Points)线段树

    D. Points time limit per test 2 seconds memory limit per test 256 megabytes input standard input out ...

  2. codeforces 295E Yaroslav and Points (离线操作+离散化+区间合并)

    参考链接:http://blog.csdn.net/dyx404514/article/details/8817717 写的很详细,这里就不再赘述,附上我的代码. #include <iostr ...

  3. codeforces Good bye 2016 E 线段树维护dp区间合并

    codeforces Good bye 2016 E 线段树维护dp区间合并 题目大意:给你一个字符串,范围为‘0’~'9',定义一个ugly的串,即串中的子串不能有2016,但是一定要有2017,问 ...

  4. Codeforces 1140F Extending Set of Points 线段树 + 按秩合并并查集 (看题解)

    Extending Set of Points 我们能发现, 如果把x轴y轴看成点, 那么答案就是在各个连通块里面的x轴的个数乘以y轴的个数之和. 然后就变成了一个并查集的问题, 但是这个题目里面有撤 ...

  5. CodeForces 19D Points (线段树+set)

    D. Points time limit per test 2 seconds memory limit per test 256 megabytes input standard input out ...

  6. Codeforces 1140F Extending Set of Points (线段树分治+并查集)

    这题有以下几个步骤 1.离线处理出每个点的作用范围 2.根据线段树得出作用范围 3.根据分治把每个范围内的点记录和处理 #include<bits/stdc++.h> using name ...

  7. codeforces 22E XOR on Segment 线段树

    题目链接: http://codeforces.com/problemset/problem/242/E E. XOR on Segment time limit per test 4 seconds ...

  8. Codeforces 588E. A Simple Task (线段树+计数排序思想)

    题目链接:http://codeforces.com/contest/558/problem/E 题意:有一串字符串,有两个操作:1操作是将l到r的字符串升序排序,0操作是降序排序. 题解:建立26棵 ...

  9. Codeforces Gym 100803G Flipping Parentheses 线段树+二分

    Flipping Parentheses 题目连接: http://codeforces.com/gym/100803/attachments Description A string consist ...

随机推荐

  1. 【原创】大数据基础之Hive(4)hive元数据库核心表结构

    1 dbs +-------+-----------------------+----------------------------------------------+------------+- ...

  2. layui框架中关于table方法级渲染和自动化渲染之间的区别简单介绍

    方法级渲染: <table class="layui-hide" id="LAY_table_user" lay-filter="user&qu ...

  3. linux进程内存布局

      一个程序本质上都是由 BSS 段.data段.text段三个组成的.这样的概念在当前的计算机程序设计中是很重要的一个基本概念,而且在嵌入式系统的设计中也非常重要,牵涉到嵌入式系统运行时的内存大小分 ...

  4. linux命令tar压缩解压

    tar -c: 建立压缩档案-x:解压-t:查看内容-r:向压缩归档文件末尾追加文件-u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中一个.下面的 ...

  5. Confluence 6 附件是如何被索引的

    当一个文件被上传到 Confluence 后,Confluence 将会尝试对文件进行解压,然后对文件中的内容进行索引.这样系统就能够允许用户对文件中的内容进行搜索,而不仅仅是搜索文件名.这个过程对系 ...

  6. JPA整合Spring案例

    目录 Spring-SpringMVC-JPA整合案例 三种整合方式 Spring整合JPA步骤 解决JPA懒加载问题 Spring-SpringMVC-JPA整合案例 author :SimpleW ...

  7. LeetCode(120):三角形最小路径和

    Medium! 题目描述: 给定一个三角形,找出自顶向下的最小路径和.每一步只能移动到下一行中相邻的结点上. 例如,给定三角形: [ [2], [3,4], [6,5,7], [4,1,8,3] ] ...

  8. 《剑指offer》栈的插入弹出序列

    本题来自<剑指offer> 栈的插入弹出序列 题目: 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2, ...

  9. linux 源码安装PHP

    解压: 解压完: configure: configure成功: make: make完成: 安装完成!!! 测试: 需要./bin/php来运行php 想要任何目录输入PHP就能使用php 方法一: ...

  10. laravel 服务提供者

    服务提供者,在laravel里面,其实就是一个工厂类.它最大的作用就是用来进行服务绑定.当我们需要绑定一个或多个服务的时候,可以自定义一个服务提供者,然后把服务绑定的逻辑都放在该类的实现中.在lara ...