【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;
总之,这种有两个限制条件的问题,一般来说就是快排维护一个条件,然后另外用数据结构维护另一个条件。
题目大意是:给定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;
总之,这种有两个限制条件的问题,一般来说就是快排维护一个条件,然后另外用数据结构维护另一个条件。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.