zoukankan      html  css  js  c++  java
  • CF 351D, 离线处理+树状数组/莫队算法

    颓颓颓

    题目大意:给你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
    ", ans[i]);
    134 
    135     return 0;
    136 }
    CF 351D
  • 相关阅读:
    package.json 字段全解析 share
    Git 使用方法
    浅谈移动前端的最佳实践(转)
    node启动服务后,窗口不能关闭。pm2了解一下
    WebSocket--客户端
    布局:多列等高布局方法
    uni-app调用支付宝、微信支付
    scss 入门基础
    mac生成iOS证书(配图)
    通过扫码打开IOS的App Store下载APP(Android版暂时没找到解决方法)
  • 原文地址:https://www.cnblogs.com/wmzisfoolish/p/5743425.html
Copyright © 2011-2022 走看看