颓颓颓
题目大意:给你m个区间询问,询问区间内有多少个不相同的数以及存不存在一种数字组成的数列为等差间隔的数列。
解:离线询问,不相同的数其实是老做法了,但是巧妙的是数字是否为等差间隔。我们把询问按右区间排序,可知等差间隔必然是连续的一段,那么从当前枚举点往左,合法数列必然是连续的一段,那么我们用树状数组+1-1维护区间延伸到哪里,然后询问[l,i]当中和是否为零就知道有没有符合的连续一段等差间隔数列了。
顺便这题官解是莫队,正好我也去研究一下莫队吧,现在先贴一个离线nlogn的做法,递归学会莫队后再来补充。
1 #include <cstdio> 2 #include <string> 3 #include <iostream> 4 #include <algorithm> 5 #include <cmath> 6 #include <cstring> 7 #include <complex> 8 #include <set> 9 #include <vector> 10 #include <map> 11 #include <queue> 12 #include <deque> 13 #include <ctime> 14 15 using namespace std; 16 17 const double EPS = 1e-8; 18 19 #define ABS(x) ((x)<0?(-(x)):(x)) 20 #define SQR(x) ((x)*(x)) 21 #define MIN(a,b) ((a)<(b)?(a):(b)) 22 #define MAX(a,b) ((a)>(b)?(a):(b)) 23 24 #define LSON(x) ((x)<<1) 25 #define RSON(x) (((x)<<1)+1) 26 #define LOWBIT(x) ((x)&(-(x))) 27 #define MAXS 1111 28 #define MAXN 222222 29 #define VOIDPOINT 0 30 #define LL long long 31 #define OO 214748364 32 #define INF 0x3f3f3f3f 33 #define MP(x,y) make_pair(x,y) 34 35 struct TreeArray{ 36 int tree[MAXN], n; 37 void clear(int nn = MAXN-10) { 38 n = nn; 39 memset(tree, 0, sizeof(tree[0])*(n+10)); 40 } 41 void add(int x, int num = 1) { 42 if (x < 1) return ; 43 while (x <= n) { 44 tree[x] += num; 45 x += LOWBIT(x); 46 } 47 } 48 int get(int x) { 49 int res = 0; 50 while (x > 0) { 51 res += tree[x]; 52 x -= LOWBIT(x); 53 } 54 return res; 55 } 56 57 } color, sl; 58 59 struct query{ 60 int l, r, id; 61 query(int a = 0, int b = 0, int c = 0): l(a), r(b), id(c) {} 62 bool operator < (const query &rhs) const { 63 return r < rhs.r; 64 } 65 } q[MAXN]; 66 67 int a[MAXN], n, m, ans[MAXN]; 68 int pre[MAXN], f[MAXN], last[MAXN]; 69 70 int main() { 71 // freopen("test.txt", "r", stdin); 72 73 74 color.clear(); sl.clear(); 75 // memset(pre, -1, sizeof(pre)); 76 memset(last, -1, sizeof(last)); 77 78 scanf("%d", &n); 79 for (int i = 1; i <= n; ++i) { 80 // cout << i << endl; 81 scanf("%d", &a[i]); 82 pre[i] = last[a[i]]; 83 if (pre[i] != -1) { 84 if (pre[pre[i]] != -1) { 85 if (i - pre[i] == pre[i] - pre[pre[i]]) f[i] = f[pre[i]]; 86 else f[i] = pre[i]; 87 } else 88 f[i] = f[pre[i]]; 89 } else 90 f[i] = -1; 91 last[a[i]] = i; 92 } 93 scanf("%d", &m); 94 for (int i = 0; i < m; ++i) { 95 int x, y; scanf("%d%d", &x, &y); 96 q[i] = query(x, y, i); 97 } 98 sort(q, q+m); 99 100 101 for (int i = 1, j = 0; i <= n; ++i) { 102 color.add(i); 103 if (pre[i] != -1) color.add(pre[i], -1); 104 105 if (pre[i] != -1) { 106 if (f[i] == f[pre[i]]) { 107 sl.add(pre[i], -1); sl.add(i); 108 } else { 109 sl.add(f[pre[i]] == -1 ? -1: pre[f[pre[i]]], 1); sl.add(pre[i], -1); 110 sl.add(pre[pre[i]], -1); sl.add(i, 1); 111 } 112 } else { 113 sl.add(i); 114 } 115 116 while (j < m && q[j].r == i) { 117 // cout << i << ‘ ‘<< q[j].l << ‘ ‘ << q[j].r << endl; 118 119 // cout << (sl.get(q[j].r) - sl.get(q[j].l-1)) << endl; 120 // cout << color.get(q[j].r) <<‘ ‘<< color.get(q[j].l-1) << endl; 121 122 ans[q[j].id] = color.get(q[j].r) - color.get(q[j].l-1) + (sl.get(q[j].r) - sl.get(q[j].l-1) == 0); 123 ++j; 124 if (i == -31) { 125 cout << i << endl; 126 for (int k = 1; k <= i; ++k) cout << color.get(k) <<‘ ‘; cout << endl; 127 for (int k = 1; k <= i; ++k) cout << a[k] <<‘ ‘; cout << endl; 128 for (int k = 1; k <= i; ++k) cout << sl.get(k) - sl.get(k-1) << ‘ ‘; cout << endl; 129 } 130 } 131 } 132 133 for (int i = 0; i < m; ++i) printf("%d\n", ans[i]); 134 135 return 0; 136 }
CF 351D
时间: 2024-10-10 05:18:29