[线段树] Chef and Array
来源:互联网 发布:因为你是范晓萱 知乎 编辑:程序博客网 时间:2024/05/16 13:50
CHEFLKJ: Chef and Array
题目描述
大厨喜欢序列和有关序列的一切。他称一个序列 V 是支配的,当且仅当存在一个数字 x(即“支配者”)其在序列中的出现次数严格超过序列长度的一半(即 ⌊|V |/2⌋)。
他的朋友 Dmytro 想让大厨开心,因此他给大厨呈现了这道有趣的题目:
给定序列 A,你需要处理 Q 个询问。询问分为两类:
• 1 x y:令序列的第 x 个元素的值为 y,即令 Ax = y;
• 2 l r:询问子序列 A[l..r] 是否是支配的,如果是则输出“Yes”,否则输出“No”。
输入格式
输入的第一行包含两个整数 N 和 Q,分别代表 A 中的元素数和需要处理的询问数。
第二行包含 N 个由空格分隔的整数,代表序列 A。
接下来 Q 行,每行描述一个询问。
输出格式
对于每个第 2 类的询问,输出一行,包含询问的回答。
数据范围
• 1 ≤ N, Q ≤ 10^5
• 1 ≤ Ai,y ≤ 10^9
• 1 ≤ x ≤ N
• 1 ≤ l ≤ r ≤ N
分析:
先用线段树+map树套树暴力存所有数,然后更新就是经典的单点更新,再处理查询。
假设x是[l,r]的支配者,根据鸽巢原理,x也必须是左儿子的支配者,或者是右儿子的支配者(否则x的个数必然不超过长度的一半,矛盾),然后发现这只是个必要条件,而非充分条件,即左右儿子的支配者不一定是节点的支配者,所以查询的时候往左右找到所有支配者,暴力判断是不是支配者。
似乎并不用启发式合并。
#include<bits/stdc++.h>#define lson rt<<1,l,mid#define rson rt<<1|1,mid+1,rusing namespace std;const int N = 1e5+5;unordered_map<int,int>tree[N<<2];int domi[N<<2];int a[N];void push_up(int rt, int len){ int lrt = rt<<1, rrt = rt<<1|1; if(tree[rt][domi[lrt]] > len) domi[rt] = domi[lrt]; else if(tree[rt][domi[rrt]] > len) domi[rt] = domi[rrt]; else domi[rt] = -1;}void build(int rt, int l, int r){ if(l == r){ tree[rt][a[l]]++; domi[rt] = a[l]; return; } int mid = (l+r)>>1; build(lson); build(rson); tree[rt] = tree[rt<<1]; for(auto x : tree[rt<<1|1]) tree[rt][x.first] += x.second; push_up(rt, (r-l+1)/2);}void update(int rt, int l, int r, int pos, int pre, int val){ if(l == r){ tree[rt].clear(); a[pos] = val; tree[rt][val]++; domi[rt] = val; return; } int mid = (l+r) >> 1; if(pos <= mid) update(lson, pos, pre, val); else update(rson, pos, pre, val); tree[rt][pre] -= 1; tree[rt][val] += 1; push_up(rt, (r-l+1)/2);}vector<int>qry;void query(int rt, int l, int r, int ql, int qr){ if(ql <= l && qr >= r){ qry.push_back(rt); return; } int mid = (l+r)>>1; if(ql <= mid) query(lson, ql, qr); if(qr > mid) query(rson, ql, qr);}int main(){ int n, q; scanf("%d%d", &n, &q); for(int i = 1; i <= n; ++i) scanf("%d", a+i); build(1, 1, n); while(q--){ int t, x, y; scanf("%d%d%d", &t, &x, &y); if(t == 1) update(1, 1, n, x, a[x], y); else{ int flag = 0; qry.clear(); query(1, 1, n, x, y); for(int i = 0; i < qry.size() && !flag; ++i){ int cnt = 0; for(int j = 0; j < qry.size() && !flag; ++j){ cnt += tree[qry[j]][domi[qry[i]]]; } if(cnt > (y-x+1)/2){ puts("Yes"); flag = 1; break; } } if(!flag) puts("No"); } }}
0 0
- [线段树] Chef and Array
- CodeChef:Chef and Subarray Queries(线段树)
- codechef Chef and Rainbow Array - 2
- [DP] Codechef .Chef And Fibonacci Array
- 【Codechef】【Chef and Graph Queries】Lct 可持久化线段树
- Little Elephant and Array 线段树
- 【线段树】295A Greg and Array
- 线段树 CodeForces 220B - Little Elephant and Array
- CodeForces 296C Greg and Array (线段树)
- CodeForces 295A Greg and Array(线段树)
- 线段树+矩阵快速幂 codeforces718C Sasha and Array
- Codeforces 718C Sasha and Array(线段树维护矩阵)
- codeforces 373div1 Sasha and Array 矩阵+线段树
- E. Sasha and Array——矩阵+线段树
- codeforces 315B Sereja and Array(单点线段树)
- CodeChef Chef and Segments
- Chef and Digits
- codechef Chef and sequence
- poj 1001 Exponentiation
- FusionCharts的使用方法
- Jquery 枚举展示
- java集合类深入分析之TreeMap/TreeSet篇
- Log4.properties配置详解
- [线段树] Chef and Array
- ActionResult 返回类型
- PAT A1002 A+B for Polynomials (25)
- ios 文件上传
- Python函数第五节
- MVC各层的典型实现
- iOS基础之属性修饰符的区别
- springMVC日期转化注释
- 仿新浪TabLayout代码片段