Yukino With Subinterval

Yukino has an array a_1, a_2 \cdots a_na1,a2⋯a**n. As a tsundere girl, Yukino is fond of studying subinterval.

Today, she gives you four integers l, r, x, yl,r,x,y, and she is looking for how many different subintervals [L, R][L,R] are in the interval [l, r][l,r] that meet the following restraints:

  1. a_L =a_{L+1} =\cdots=a_Ra**L=a**L+1=⋯=a**R, and for any i \in [L,R], x \le a_i \le yi∈[L,R],xa**iy.
  2. The length of such a subinterval should be maximum under the first restraint.

Note that two subintervals [L_1,R_1] , [L_2,R_2][L1,R1],[L2,R2]are different if and only if at least one of the following formulas is true:

  1. L1 \cancel= L2L1=L2
  2. R1 \cancel= R2R1=R2

Yukino, at the same time, likes making tricks. She will choose two integers pos,vpos,v, and she will change a_{pos}apo**s to vv.

Now, you need to handle the following types of queries:

  • 11 pos \ vpos v: change a_{pos}apo**s to vv
  • 22 l \ r \ x \ yl r x y: print the number of legal subintervals in the interval [l, r][l,r]

Input

The first line of the input contains two integers n, m (1 \le n, m \le 2 \times 10^5)n,m(1≤n,m≤2×105) – the numbers of the array and the numbers of queries respectively.

The second line of the input contains nn integers a_i (1 \le a_i \le n)a**i(1≤a**in).

For the next mm line, each containing a query in one of the following queries:

  • 11 pospos vv (1 \le pos, v \le n)(1≤pos,vn): change a_{pos}apo**s to vv
  • 22 l \ r \ x \ yl r x y (1 \le l \le r \le n) (1 \le x \le y \le n)(1≤lrn)(1≤xyn): print the number of legal subintervals in the interval [l,r][l,r]

Output

For each query of the second type, you should output the number of legal subintervals in the interval [l, r][l,r].

样例输入复制

  1. 6 3
  2. 3 3 1 5 6 5
  3. 2 2 3 4 5
  4. 1 3 2
  5. 2 1 6 1 5

样例输出复制

  1. 0
  2. 4

样例解释

For the first operations, there are 33 different subintervals ([2, 2],[3, 3],[2,3])([2,2],[3,3],[2,3]) in the interval [2, 3][2,3], but none of them meets all the restraints.

For the third operations, the legal subintervals in interval [1, 6][1,6] are: [1, 2], [3, 3], [4, 4], [6, 6][1,2],[3,3],[4,4],[6,6]

Notes that although subintervals [1,1][1,1] and [2,2][2,2] also meet the first restraint, we can extend them to subinterval [1, 2][1,2]. So the length of them is not long enough, which against the second one.

题目链接:https://nanti.jisuanke.com/t/41356

题意:

给你一个含有n个数的数组,和m个操作

操作1:

将a[pos] 变为val

操作2:

询问在\([l,r]\) 中有多少个子区间满足数值在$[x,y] $ 之间 ,每一个子区间是长度尽可能大的相同数字。

思路:

将数组中 $a[i] $ ,转为在二维坐标平面上的点\((i,a[i])\) ,

那么就转为了一个带修改的二维平面中询问矩阵内点权值和的问题。

这是一个经典的三维偏序问题。

可以用CDQ分治来解决。

不会的话可以先学习一下这题:

https://www.cnblogs.com/qieqiemin/p/11613573.html

本题还需要注意几点:

因为连续相同的数值只贡献一个,所以我们把连续相同的只把第一个点放入平面中(即放入cdq的离线操作中)

那么对于每一个询问,我们就要特判一下\((l,a[l])\) 这个点,如果\(a[l]\) 在 \([x,y]\) 之间,并且 满足

$l >1 $

$a[l]==a[l-1] $

这2个条件,都需要对这个询问的答案加上1。即加上a[l]为开头的子区间的贡献,

以及修改操作,需要判断改变\(a[i]\) 对\(a[i-1],a[i+1]\) 的影响,以及如果更改前的\(a[i]\) 是一个子区间的开头,需要去掉原来的影响(加上相反的值即可。)

代码:

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <cmath>
  6. #include <queue>
  7. #include <stack>
  8. #include <map>
  9. #include <set>
  10. #include <vector>
  11. #include <iomanip>
  12. #define ALL(x) (x).begin(), (x).end()
  13. #define sz(a) int(a.size())
  14. #define rep(i,x,n) for(int i=x;i<n;i++)
  15. #define repd(i,x,n) for(int i=x;i<=n;i++)
  16. #define pii pair<int,int>
  17. #define pll pair<long long ,long long>
  18. #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
  19. #define MS0(X) memset((X), 0, sizeof((X)))
  20. #define MSC0(X) memset((X), '\0', sizeof((X)))
  21. #define pb push_back
  22. #define mp make_pair
  23. #define fi first
  24. #define se second
  25. #define eps 1e-6
  26. #define gg(x) getInt(&x)
  27. #define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
  28. #define du3(a,b,c) scanf("%d %d %d",&(a),&(b),&(c))
  29. #define du2(a,b) scanf("%d %d",&(a),&(b))
  30. #define du1(a) scanf("%d",&(a));
  31. using namespace std;
  32. typedef long long ll;
  33. ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
  34. ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
  35. ll powmod(ll a, ll b, ll MOD) {a %= MOD; if (a == 0ll) {return 0ll;} ll ans = 1; while (b) {if (b & 1) {ans = ans * a % MOD;} a = a * a % MOD; b >>= 1;} return ans;}
  36. void Pv(const vector<int> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%d", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}}
  37. void Pvl(const vector<ll> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%lld", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}}
  38. inline void getInt(int *p);
  39. const int maxn = 1000010;
  40. const int inf = 0x3f3f3f3f;
  41. /*** TEMPLATE CODE * * STARTS HERE ***/
  42. ll tree[maxn];
  43. int lowbit(int x)
  44. {
  45. return -x & x;
  46. }
  47. ll ask(int x)
  48. {
  49. // cout<<x<<" ";
  50. ll res = 0ll;
  51. while (x) {
  52. res += tree[x];
  53. x -= lowbit(x);
  54. }
  55. // cout<<res<<endl;
  56. return res;
  57. }
  58. void add(int x, ll val)
  59. {
  60. // cout<<x<<" "<<val<<endl;
  61. while (x < maxn) {
  62. tree[x] += val;
  63. x += lowbit(x);
  64. }
  65. }
  66. int n, m;
  67. struct node {
  68. int time;
  69. int op;
  70. int x, y;
  71. int val;
  72. int ansid;
  73. node() {}
  74. node(int tt, int oo, int xx, int yy, int vv, int aa)
  75. {
  76. time = tt;
  77. op = oo;
  78. x = xx;
  79. y = yy;
  80. val = vv;
  81. ansid = aa;
  82. }
  83. bool operator < (const node &bb) const
  84. {
  85. if (time != bb.time) {
  86. return time < bb.time;
  87. } else if (x != bb.x) {
  88. return x < bb.x;
  89. } else if (y != bb.y) {
  90. return y < bb.y;
  91. } else {
  92. return op < bb.op;
  93. }
  94. }
  95. bool operator<= (const node &bb )const
  96. {
  97. if (x != bb.x) {
  98. return x < bb.x;
  99. } else if (y != bb.y) {
  100. return y < bb.y;
  101. } else {
  102. return op < bb.op;
  103. }
  104. }
  105. } a[maxn], b[maxn];
  106. int ans[maxn];
  107. int tot;
  108. int anstot;
  109. int c[maxn];
  110. int sym[maxn];
  111. void cdq(int l, int r)
  112. {
  113. if (l == r) {
  114. return ;
  115. }
  116. int mid = (l + r) >> 1;
  117. cdq(l, mid);
  118. cdq(mid + 1, r);
  119. int ql = l;
  120. int qr = mid + 1;
  121. repd(i, l, r) {
  122. if (qr > r || (ql <= mid && a[ql] <= a[qr])) {
  123. if (a[ql].op == 1) {
  124. add(a[ql].y, a[ql].val);
  125. sym[i] = 1;
  126. }
  127. b[i] = a[ql++];
  128. } else {
  129. if (a[qr].op == 2) {
  130. ans[a[qr].ansid] += a[qr].val * ask(a[qr].y);
  131. }
  132. b[i] = a[qr++];
  133. }
  134. }
  135. ql = l;
  136. qr = mid + 1;
  137. repd(i, l, r) {if (qr > r || (ql <= mid && a[ql] <= a[qr])) {if (a[ql].op == 1) {add(a[ql].y, -a[ql].val);} ql++;} else {qr++;}}
  138. repd(i, l, r) {a[i] = b[i];}
  139. }
  140. int main()
  141. {
  142. //freopen("D:\\code\\text\\input.txt","r",stdin);
  143. //freopen("D:\\code\\text\\output.txt","w",stdout);
  144. du2(n, m);
  145. repd(i, 1, n) {
  146. du1(c[i]);
  147. if (c[i] != c[i - 1]) {
  148. a[++tot] = node(-1, 1, i, c[i], 1, 0);
  149. }
  150. }
  151. // node(int tt, int oo, int xx, int yy, int vv, int aa)
  152. repd(i, 1, m) {
  153. int op;
  154. du1(op);
  155. if (op == 1) {
  156. int pos, v;
  157. du2(pos, v);
  158. if (pos != n && c[pos] == c[pos + 1]) {
  159. a[++tot] = node(i, 1, pos + 1, c[pos + 1], 1, 0);
  160. }
  161. if (pos == 1 || c[pos] != c[pos - 1]) {
  162. a[++tot] = node(i, 1, pos, c[pos], -1, 0);
  163. }
  164. c[pos] = v;
  165. if (pos != n && c[pos] == c[pos + 1]) {
  166. a[++tot] = node(i, 1, pos + 1, c[pos + 1], -1, 0);
  167. }
  168. if (pos == 1 || c[pos] != c[pos - 1]) {
  169. a[++tot] = node(i, 1, pos, c[pos], 1, 0);
  170. }
  171. } else {
  172. int l, r, x, y;
  173. du2(l, r);
  174. du2(x, y);
  175. if (l != 1 && c[l] == c[l - 1] && c[l] <= y && c[l] >= x) {
  176. ans[anstot]++;
  177. }
  178. a[++tot] = node(i, 2, r, y, 1, anstot);
  179. a[++tot] = node(i, 2, l - 1, x - 1, 1, anstot);
  180. a[++tot] = node(i, 2, r, x - 1, -1, anstot);
  181. a[++tot] = node(i, 2, l - 1, y, -1, anstot++);
  182. }
  183. }
  184. sort(a + 1, a + 1 + tot);
  185. cdq(1, tot);
  186. repd(i, 0, anstot - 1) {
  187. printf("%d\n", max(ans[i], 0));
  188. }
  189. return 0;
  190. }
  191. inline void getInt(int *p)
  192. {
  193. char ch;
  194. do {
  195. ch = getchar();
  196. } while (ch == ' ' || ch == '\n');
  197. if (ch == '-') {
  198. *p = -(getchar() - '0');
  199. while ((ch = getchar()) >= '0' && ch <= '9') {
  200. *p = *p * 10 - ch + '0';
  201. }
  202. } else {
  203. *p = ch - '0';
  204. while ((ch = getchar()) >= '0' && ch <= '9') {
  205. *p = *p * 10 + ch - '0';
  206. }
  207. }
  208. }

2019 ICPC 南昌网络赛I:Yukino With Subinterval(CDQ分治)的更多相关文章

  1. 2019南昌网络赛I:Yukino With Subinterval(CDQ) (树状数组套主席树)

    题意:询问区间有多少个连续的段,而且这段的颜色在[L,R]才算贡献,每段贡献是1. 有单点修改和区间查询. 思路:46min交了第一发树套树,T了. 稍加优化多交几次就过了. 不难想到,除了L这个点, ...

  2. 2019 ICPC 南昌网络赛

    2019 ICPC 南昌网络赛 比赛时间:2019.9.8 比赛链接:The 2019 Asia Nanchang First Round Online Programming Contest 总结 ...

  3. 2019南昌网络赛-I. Yukino With Subinterval 线段树套树状数组,CDQ分治

    TMD...这题卡内存卡的真优秀... 所以以后还是别用主席树的写法...不然怎么死的都不知道... 树套树中,主席树方法开权值线段树...会造成空间的浪费...这道题内存卡的很紧... 由于树套树已 ...

  4. 2019 ICPC南昌网络赛 B题

    英雄灭火问题忽略了一点丫 一个超级源点的事情,需要考虑周全丫 2 #include<cstdio> #include<cstring> #include<queue> ...

  5. Magic Master(2019年南昌网络赛E题+约瑟夫环)

    目录 题目链接 题意 思路 代码 题目链接 传送门 题意 初始时你有\(n\)张牌(按顺序摆放),每一次操作你将顶端的牌拿出,然后按顺序将上面的\(m\)张牌放到底部. 思路 首先我们发下拿走\(1\ ...

  6. 2019年ICPC南昌网络赛 J. Distance on the tree 树链剖分+主席树

    边权转点权,每次遍历到下一个点,把走个这条边的权值加入主席树中即可. #include<iostream> #include<algorithm> #include<st ...

  7. 2019 ICPC上海网络赛 A 题 Lightning Routing I (动态维护树的直径)

    题目: 给定一棵树, 带边权. 现在有2种操作: 1.修改第i条边的权值. 2.询问u到其他一个任意点的最大距离是多少. 题解: 树的直径可以通过两次 dfs() 的方法求得.换句话说,到任意点最远的 ...

  8. 2019 ICPC 沈阳网络赛 J. Ghh Matin

    Problem Similar to the strange ability of Martin (the hero of Martin Martin), Ghh will random occurr ...

  9. 2019 ICPC 徐州网络赛 B.so easy (并查集)

    计蒜客链接:https://nanti.jisuanke.com/t/41384 题目大意:给定n个数,从1到n排列,其中有q次操作,操作(1) 删除一个数字 // 操作(2)求这个数字之后第一个没有 ...

随机推荐

  1. 【VS开发】图像颜色

    版权声明:本文为博主原创文章,转载请注明出处http://blog.csdn.net/lg1259156776/. 最近被图像颜色整的乱七八糟的,一会儿YUV422,一会儿RGB,一会儿gray... ...

  2. js模板(template.js)实现页面动态渲染

    template.js是由纯JavaScript编写的第三方模板引擎.点击https://github.com/yanhaijing/template.js可进行下载. 在页头导入模板文件 <s ...

  3. vim中文帮助手册的安装

    1. 下载: 下载页面:http://vimcdoc.sourceforge.net/ 选择“Latest platform independent tarball, including an Lin ...

  4. 洛谷 题解 P1220 【关路灯 】

    搜索 传参 inline void DFS(int now,int l,int r,int cnt,int sum,int k) /* now为当前点 l为左端点 r为右端点 cnt为当前耗电量 su ...

  5. Minimizing Difference 【思维】

    题目链接: https://vjudge.net/contest/336389#problem/B 题目大意: 给出一个长度为n的数列以及操作次数k.k的范围为1e14.每次操作都可以选择给任意一个数 ...

  6. Android使用glide加载.9图片的方法

    我们在开发过程中会经常使用.9图片, 因为它可以使图片拉伸的时候,保证其不会失真. 而我们把.9图片放在服务器端,通过glide直接加载,会报错. 我们的解决方法是 通过sdk的aapt工具 把.9图 ...

  7. [转帖]强大的strace命令用法详解

    强大的strace命令用法详解 文章转自: https://www.linuxidc.com/Linux/2018-01/150654.htm strace是什么? 按照strace官网的描述, st ...

  8. oracle中Blob、Clob、Varchar之间的互相转换

    以下是oracle中Blob.Clob.Varchar之间的互相转换(都是百度找的,亲测可用) Blob转Varchar2: CREATE OR REPLACE FUNCTION blob_to_va ...

  9. linux 从远程服务器拷贝文件

    1.从服务器复制文件到本地: scp root@192.168.1.100:/data/test.txt /home/myfile/ 2.从服务器复制文件夹到本地: scp -r root@192.1 ...

  10. Java数组定义及方法

    数组的描述   在数组中每个元素都具有相同的数据类型,是有序数据的集合.通俗的说数组就相当于一个容器.数组分为一维数组.二维数组和多维数组. 数组的特点: 数组类型是从抽象基类 Array 派生的引用 ...