zoukankan      html  css  js  c++  java
  • 牛客国庆训练 H.千万别用树套树

    链接https://ac.nowcoder.com/acm/contest/1108/H

    国庆队内训练的题,当时还完全没思路,就没补。现在会树状数组了,倒是能想一想,不过网上题解好多用线段树传数组的?我看不太懂,觉得还是树状数组维护方便多了。

    建两颗BIT维护分别维护左右端点。

    由于对于第二种询问操作,ri-li<=2,带来了极大的便利。直接用已插入的总数-左端点大于l的线段个数-右端点小于r的线段个数即可,但有种情况需要特判。

    而我网上看的题解,大部分都忽略了一个问题,就是线段退化成点的问题,样例里也给出了这样的情况,显然对于操作2,ri-li==2时,这样退化的线段会被减去两次,但令人惊讶的是数据出水了,导致不考虑这个问题也能AC。。。。。。

    比如说 

    3 3

    1 2 2

    1 2 2

    2 1 3

    这组数据网上大部分的题解的代码会输出-2,中间这个点被减了两遍。

    应对也很简单,再用一个数组在插入时,保存l==r的单独的点即可,询问时在加上。

     1 #include <bits/stdc++.h>
     2 #define debug(x) cout << #x << ": " << x << endl
     3 using namespace std;
     4 typedef long long ll;
     5 const int MAXN=1e5+7;
     6 const int INF=0x3f3f3f3f;
     7 const int MOD=1e9+7;
     8 
     9 int sol[MAXN];
    10 
    11 struct BIT
    12 {
    13     int c[MAXN];
    14     int lowbit(int x){return x&(-x);}
    15     void add(int i,int x)
    16     {
    17         while(i<MAXN)
    18         {
    19             c[i]+=x;
    20             i+=lowbit(i);
    21         }
    22     }
    23     ll sum(int i)
    24     {
    25         ll res=0;
    26         while(i)
    27         {
    28             res+=c[i];
    29             i-=lowbit(i);
    30         }
    31         return res;
    32     }
    33 }L,R;
    34 
    35 int main()
    36 {
    37     int n,q;
    38     while(~scanf("%d%d",&n,&q))
    39     {
    40         memset(L.c,0,sizeof(L.c));
    41         memset(R.c,0,sizeof(R.c));
    42         memset(sol,0,sizeof(sol));
    43         int cnt=0;
    44         int ans=0;
    45         while(q--)
    46         {
    47             int op,l,r;
    48             scanf("%d%d%d",&op,&l,&r);
    49             if(op==1)
    50             {
    51                 if(l==r) sol[l]++;
    52                 L.add(l,1);
    53                 R.add(r,1);
    54                 cnt++;
    55             }
    56             else
    57             {
    58                 int t1=cnt-L.sum(l);
    59                 int t2=R.sum(r-1);
    60                 ans=cnt-t1-t2;
    61                 if(r-l==2) ans+=sol[l+1];
    62                 printf("%d
    ",ans);
    63             }
    64         }
    65     }
    66     return 0;
    67 }
    View Code
  • 相关阅读:
    欧拉工程第72题:Counting fractions
    欧拉工程第71题:Ordered fractions
    欧拉工程第70题:Totient permutation
    欧拉工程第69题:Totient maximum
    欧拉工程第68题:Magic 5-gon ring
    欧拉工程第67题:Maximum path sum II
    欧拉工程第66题:Diophantine equation
    欧拉工程第65题:Convergents of e
    欧拉工程第64题:Odd period square roots
    欧拉工程第63题:Powerful digit counts
  • 原文地址:https://www.cnblogs.com/Zzqf/p/11791333.html
Copyright © 2011-2022 走看看