• 线段树加离散化


      1 #include<cstdio>
      2 #include<algorithm>
      3 using namespace std;
      4 const int maxn=1e5+5;
      5 int a[maxn];
      6 int k[maxn];
      7 struct note
      8 {
      9     int left, right, sum;
     10 }tree[maxn*4];
     11 void pushup(int id)
     12 {
     13     tree[id].sum=tree[id<<1].sum+tree[id<<1|1].sum;
     14 }
     15 void build(int id, int l, int r)
     16 {
     17     tree[id].left=l; tree[id].right=r;
     18     if(l==r) tree[id].sum=0;
     19     else
     20     {
     21         int mid=(l+r)/2;
     22         build(id<<1, l, mid);
     23         build(id<<1|1, mid+1, r);
     24         pushup(id);
     25     }
     26 }
     27 int query(int id, int l, int r)
     28 {
     29     if(l<=tree[id].left && tree[id].right<=r)
     30     {
     31         return tree[id].sum;
     32     }
     33     else
     34     {
     35         int ans=0;
     36         int mid=(tree[id].left+tree[id].right)/2;
     37         if(l<=mid) ans+=query(id<<1, l, r);
     38         if(r>mid) ans+=query(id<<1|1, l, r);
     39         return ans;
     40     }
     41 }
     42 void update(int id, int pos)
     43 {
     44     if(tree[id].left==tree[id].right)
     45     {
     46         tree[id].sum++;
     47     }
     48     else
     49     {
     50         int mid=(tree[id].left+tree[id].right)/2;
     51         if(pos<=mid) update(id<<1, pos);
     52         else update(id<<1|1, pos);
     53         pushup(id);
     54     }
     55 }
     56 int findk(int key, int n)查找对应位置的值。。。
     57 {
     58     int l=1, r=n;
     59     while(l<=r)
     60     {
     61         int mid=(l+r)>>1;
     62         if(k[mid]==key)
     63             return mid;
     64         else
     65         {
     66             if(key<k[mid])
     67                 r=mid-1;
     68             else
     69                 l=mid+1;
     70         }
     71     }
     72 }
     73 int main()
     74 {
     75     int n, m=1;
     76     scanf("%d", &n);
     77     for(int i=1; i<=n; i++)
     78     {
     79         scanf("%d", &a[i]);
     80         k[i]=a[i];
     81     }
     82     sort(k+1, k+1+n);
     83     for(int i=2; i<=n; i++)去重
     84     {
     85         if(k[i]!=k[i-1])
     86             k[++m]=k[i];
     87     }
     88     int t=m;
     89     for(int i=1; i<=t-1; i++)弥补普通离散化的缺陷
     90     {
     91         if(k[i]+1!=k[i+1])
     92         {
     93             k[++m]=k[i]+1;
     94         }
     95     }
     96     sort(k+1, k+1+m);
     97     int ans=0;
     98     build(1, 1, maxn); 
     99     for(int i=1; i<=n; i++)
    100     {
    101         ans+=query(1, findk(a[i], m)+1, maxn);
    102         update(1, findk(a[i], m));
    103     }
    104     printf("%d", ans);
    105 
    106 }

    普通离散化缺点:

    例子一:1-10 1-4 5-10
    普通离散化后都变成了[1,4][1,2][3,4]

    线段2覆盖了[1,2],线段3覆盖了[3,4],那么线段1被完全覆盖,而实际并没有覆盖。

    解决方法:离散化时,要对相邻的数字,在离散化时中间加一个数字

  • 相关阅读:
    setMasksToBounds
    CSRF跨站
    ORM: object relationship mapping
    orm查询
    图书管理系统(增删改)
    django图书管理半成品(MySQL)
    模板继承(练习测试)
    模板层(template)
    django命令(笔记,自己看的)
    django(注册→登录→主页)增强版
  • 原文地址:https://www.cnblogs.com/dongdong25800/p/9390536.html
Copyright © 2020-2023  润新知