zoukankan      html  css  js  c++  java
  • [CQOI2015]任务查询系统

    嘟嘟嘟


    很显然是主席树啊。


    首先要稍微想想:主席树的板子是单点插入,区间查询,而区间询问是用的是前缀和相减。但这道题是区间修改,单点查询。插入和查询操作是相反的。
    那么就能想到前缀和的逆运算——差分。首先把修改区间拆成(L)(R + 1)两个时间点,然后按时间排序,遇到(L)就把对应的优先级(+1),并且在这个点上加上这个优先级;遇到(R + 1)就减去。
    需要注意的是每一个时间点首先要继承上一个时间点的线段树的信息,写的时候继承根就行了。
    最后还要注意的一点就是查询时递归到(l ==r)的时候应该返回(sum[now] / num[now] * k),因为可能有重复的数,而且当前要取得(k)个数比这些重复的数的个数少。
    啊,对了,优先级要离散化。

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #include<cctype>
    #include<vector>
    #include<stack>
    #include<queue>
    using namespace std;
    #define enter puts("") 
    #define space putchar(' ')
    #define Mem(a, x) memset(a, x, sizeof(a))
    #define rg register
    typedef long long ll;
    typedef double db;
    const int INF = 0x3f3f3f3f;
    const db eps = 1e-8;
    const int maxn = 1e6 + 5;
    const int maxt = 1e7 + 5;
    inline ll read()
    {
      ll ans = 0;
      char ch = getchar(), last = ' ';
      while(!isdigit(ch)) last = ch, ch = getchar();
      while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
      if(last == '-') ans = -ans;
      return ans;
    }
    inline void write(ll x)
    {
      if(x < 0) x = -x, putchar('-');
      if(x >= 10) write(x / 10);
      putchar(x % 10 + '0');
    }
    
    int n, m, Max = 0;
    struct Node
    {
      int x, num, d;
      bool operator < (const Node& oth)const
      {
        return x < oth.x || (x == oth.x && num < oth.num);
      }
    }a[maxn << 1];
    int b[maxn];
    
    struct Tree
    {
      int ls, rs, num; ll sum;
    }t[maxt];
    int root[maxn], cnt = 0;
    void insert(int old, int& now, int l, int r, int id, int dn, int ds)
    {
      t[now = ++cnt] = t[old];
      t[now].num += dn; t[now].sum += ds;
      if(l == r) return;
      int mid = (l + r) >> 1;
      if(id <= mid) insert(t[old].ls, t[now].ls, l, mid, id, dn, ds);
      else insert(t[old].rs, t[now].rs, mid + 1, r,id, dn, ds);
    }
    ll query(int now, int l, int r, int id)
    {
      if(l == r) return t[now].sum / t[now].num * (ll)id;
      int mid = (l + r) >> 1, Num = t[t[now].ls].num;
      if(id < Num) return query(t[now].ls, l, mid, id);
      else if(id == Num) return t[t[now].ls].sum;
      else return t[t[now].ls].sum + query(t[now].rs, mid + 1, r, id - Num);
    }
    
    int main()
    {
      n = read(); m = read();
      int tot = 0;
      for(int i = 1, L, R, x; i <= n; ++i)
        {
          L = read(), R = read(), x = read();
          a[++tot] = (Node){L, x, 1};
          a[++tot] = (Node){R + 1, -x, -1};
          b[i] = x;
        }
      sort(a + 1, a + tot + 1);
      sort(b + 1, b + n + 1);
      int _n = unique(b + 1, b + n + 1) - b - 1;
      for(int i = 1, j = 1; i <= m + 1; ++i)
        {
          root[i] = root[i - 1];
          while(a[j].x == i && j <= tot)
    	{
    	  int id = lower_bound(b + 1, b + _n + 1, abs(a[j].num)) - b;
    	  insert(root[i], root[i], 1, _n, id, a[j].d, a[j].num);
    	  j++;
    	}
        }
      ll ans = 1;
      for(int i = 1; i <= m; ++i)
        {
          int x = read(); ll A = read(), B = read(), C = read();
          int k = 1 + (A * ans % C + B) % C;
    	  if(k >= t[root[x]].num) ans = t[root[x]].sum;
          else ans = query(root[x], 1, _n, k);
          write(ans), enter;
        }
      return 0;
    }
    
  • 相关阅读:
    Different AG groups have the exactly same group_id value if the group names are same and the ‘CLUSTER_TYPE = EXTERNAL/NONE’
    An example of polybase for Oracle
    use azure data studio to create external table for oracle
    Missing MSI and MSP files
    You may fail to backup log or restore log after TDE certification/key rotation.
    Password is required when adding a database to AG group if the database has a master key
    Use KTPASS instead of adden to configure mssql.keytab
    ardunio+舵机
    android webview 全屏100%显示图片
    glide 长方形图片显示圆角问题
  • 原文地址:https://www.cnblogs.com/mrclr/p/10066664.html
Copyright © 2011-2022 走看看