【find】 字符串?树状数组~

     一道吐血的字符串题。
       题目大意是:给定n(n<=50000)个字符串,长度不超过100,同时给出q(q<=50000)个询问,一个询问包括两个字符串
a,b,问一开始给出的n个字符串中,有多少个字符串,满足它的前缀是a,后缀是b。
        考场上看到题目注释了一句:字符串的公共前缀较少,所以很happy打了个猥琐方法,先把n个字符串按照字典序排序,用二分缩小枚举范围,结果,每个数据都给了一堆length(a)=1 or length(b)=1的询问(#.#)..........
       考试后把各种沾得上边的东西全想了一下(包括字典树套字典树,字典树套线段树,网络流加离线回答.......这写恶心东西),
当得知solution 给出的树状数组的时候,被无语到了.........


 =========================================以上都是背景=================================================  
       其实仔细想了一下后,发现了其树状数组的本质.............
       之前我想用网络流离线回答的时候,其实离树状数组已经不远了。


        我的想法是,分别将n个字符串按字典序排序,在把他们倒过来按字典序排序,构成两个数组,不妨按照二分图的叫法,称他们为X 部,Y 部,把字符串抽象称点.........(看起来真的比较像二分图,所以去想网络流哩0.0)
        把X,Y部中表示同一字符串的进行连边,然后询问可以看成是X部上的一段区间和Y 部上的一段区间,当然,很容易想到网络流找有几条边满足询问(脚趾头都知道丑的像渣一样.......),然后,这个问题其实是可以转化为树状数组的。
       观察这个问题的性质,有两个限制条件,类比二维偏序的快排加树状数组,这个问题也可以用类似的东西来做。
        把X部上的区间的端点离散出来,从大到小枚举之,然后不断插入边,利用树状数组以及容斥原理计算。
             比如:
                                                                      A                         B
                            “X 部”    ============i============i=========================
                                                    /        \                       /   \                     /
                                                   /           \                   /      \                  /
                                                  /             \                /         \               /
                             “Y部”    ===================i==============i================
                                                                                     C                             D
    
                                 [A,B]与[C,D] 对应的是一个询问
                                我们从左往右扫X部,当遇到左端点A时,保证x部端点小于A 的 线段数量全部加入树状数组,统计此时C,D之间的线段数量为  ans1,然后扫到右端点B时, 同样保证x部端点小于B的 线段数量全部加入树状数组,统计此时C,D之间的线段数量为ans2,根据容斥原理,得到这个询问的答案 为ans2-ans1;


             总之,这种有两个限制条件的问题,一般来说就是快排维护一个条件,然后另外用数据结构维护另一个条件。  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章