Codeforces 666E E - Forensic Examination SA + 莫队 + 线段树
我也不知道为什么这个复杂度能过, 而且跑得还挺快, 数据比较水?
在sa上二分出上下界, 然后莫队 + 线段树维护区间众数。
- #include<bits/stdc++.h>
- #define LL long long
- #define fi first
- #define se second
- #define mk make_pair
- #define PLL pair<LL, LL>
- #define PLI pair<LL, int>
- #define PII pair<int, int>
- #define SZ(x) ((int)x.size())
- #define ull unsigned long long
- using namespace std;
- const int N = 6e5 + ;
- const int inf = 0x3f3f3f3f;
- const LL INF = 0x3f3f3f3f3f3f3f3f;
- const int mod = 1e9 + ;
- const double eps = 1e-;
- const double PI = acos(-);
- #define F(x) ((x) / 3 + ((x) % 3 == 1 ? 0 : tb))
- #define G(x) ((x) < tb ? (x) * 3 + 1 : ((x) - tb) * 3 + 2)
- int r[ * N], sa[ * N];
- int wa[ * N], wb[ * N], wv[ * N], ss[ * N];
- int rnk[N], lcp[N];
- int c0(int *r, int a, int b) {return r[a] == r[b] && r[a + ] == r[b + ] && r[a + ] == r[b + ]; }
- int c12(int k, int *r, int a, int b) {
- if(k == ) return r[a] < r[b] || r[a] == r[b] && c12(, r, a + , b + );
- return r[a] < r[b] || r[a] == r[b] && wv[a + ] < wv[b + ];
- }
- void sort(int *r, int *a, int *b, int n, int m) {
- for(int i = ; i < n; i++) wv[i] = r[a[i]];
- for(int i = ; i < m; i++) ss[i] = ;
- for(int i = ; i < n; i++) ss[wv[i]]++;
- for(int i = ; i < m; i++) ss[i] += ss[i - ];
- for(int i = n - ; i >= ; i--) b[--ss[wv[i]]] = a[i];
- }
- void DC3(int *r, int *sa, int n, int m) {
- int i, j, p;
- int *san = sa + n, *rn = r + n;
- int ta = , tb = (n + ) / , tbc = ;
- r[n] = r[n + ] = ;
- for(i = ; i < n; i++) if(i % != ) wa[tbc++] = i;
- sort(r + , wa, wb, tbc, m);
- sort(r + , wb, wa, tbc, m);
- sort(r, wa, wb, tbc, m);
- for(p = , rn[F(wb[])] = , i = ; i < tbc; i++)
- rn[F(wb[i])] = c0(r, wb[i - ], wb[i]) ? p - : p++;
- if(p < tbc) DC3(rn, san, tbc, p);
- else for(i = ; i < tbc; i++) san[rn[i]] = i;
- for(i = ; i < tbc; i++) if(san[i] < tb) wb[ta++] = san[i] * ;
- if(n % == ) wb[ta++] = n - ;
- sort(r, wb, wa, ta, m);
- for(i = ; i < tbc; i++) wv[wb[i] = G(san[i])] = i;
- for(i = , j = , p = ; i < ta && j < tbc; p++)
- sa[p] = c12(wb[j] % , r, wa[i], wb[j]) ? wa[i++] : wb[j++];
- for( ; i < ta; p++) sa[p] = wa[i++];
- for( ; j < tbc; p++) sa[p] = wb[j++];
- }
- void calc_LCP(int *r, int *sa, int n) {
- int k = ;
- for(int i = ; i < n; i++) rnk[sa[i]] = i;
- for(int i = ; i < n - ; lcp[rnk[i++]] = k) {
- if(k) k--;
- for(int j = sa[rnk[i] - ]; r[i + k] == r[j + k]; k++);
- }
- }
- int Log[N];
- struct ST {
- int dp[N][], ty;
- void build(int n, int b[], int _ty) {
- ty = _ty;
- for(int i = -(Log[]=-); i < N; i++)
- Log[i] = Log[i - ] + ((i & (i - )) == );
- for(int i = ; i <= n; i++) dp[i][] = ty * b[i];
- for(int j = ; j <= Log[n]; j++)
- for(int i = ; i+(<<j)- <= n; i++)
- dp[i][j] = max(dp[i][j-], dp[i+(<<(j-))][j-]);
- }
- inline int query(int x, int y) {
- int k = Log[y - x + ];
- return ty * max(dp[x][k], dp[y-(<<k)+][k]);
- }
- };
- namespace SGT {
- #define lson l, mid, rt << 1
- #define rson mid + 1, r, rt << 1 | 1
- const int N = 5e4 + ;
- PII a[N << ];
- int b[N];
- void build(int l, int r, int rt) {
- if(l == r) {
- a[rt].se = -l;
- b[l] = rt;
- return;
- }
- int mid = (l + r) >> ;
- build(lson); build(rson);
- a[rt] = max(a[rt << ], a[rt << | ]);
- }
- inline void update(int x, int val) {
- x = b[x];
- a[x].fi += val;
- x >>= ;
- for( ; x; x >>= )
- a[x] = max(a[x << ], a[x << | ]);
- }
- PII query(int L, int R, int l, int r, int rt) {
- if(R < l || r < L) return mk(-inf, inf);
- if(L <= l && r <= R) return a[rt];
- int mid = (l + r) >> ;
- return max(query(L, R, lson), query(L, R, rson));
- }
- }
- struct Qus {
- int L, R, numl, numr, id;
- bool operator < (const Qus& rhs) const {
- if(L / == rhs.L / ) return R < rhs.R;
- return L < rhs.L;
- }
- };
- int n, m, q, mxc = , who[N];
- PII ans[N];
- char s[N];
- ST rmq;
- Qus qus[N];
- int main() {
- scanf("%s", s);
- for(int i = ; s[i]; i++)
- r[n++] = s[i], mxc = max(mxc, (int)s[i]);
- scanf("%d", &m);
- for(int i = ; i <= m; i++) {
- r[n++] = mxc++;
- scanf("%s", s);
- for(int j = ; s[j]; j++)
- r[n] = s[j], who[n++] = i;
- }
- r[n] = ;
- DC3(r, sa, n + , mxc);
- calc_LCP(r, sa, n + );
- rmq.build(n, lcp, -);
- scanf("%d", &q);
- for(int i = ; i <= q; i++) {
- int l, r, pl, pr;
- scanf("%d%d%d%d", &l, &r, &pl, &pr);
- int pos = rnk[pl - ], len = pr - pl + ;
- int low = , high = pos - , L = pos, R = pos;
- while(low <= high) {
- int mid = (low + high) >> ;
- if(rmq.query(mid + , pos) >= len) L = mid, high = mid - ;
- else low = mid + ;
- }
- low = pos + , high = n;
- while(low <= high) {
- int mid = (low + high) >> ;
- if(rmq.query(pos + , mid) >= len) R = mid, low = mid + ;
- else high = mid - ;
- }
- qus[i] = Qus{L, R, l, r, i};
- }
- SGT::build(, m, );
- sort(qus + , qus + + q);
- int l = , r = ;
- for(int i = ; i <= q; i++) {
- int L = qus[i].L, R = qus[i].R, numl = qus[i].numl, numr = qus[i].numr;
- while(r < R) r++, SGT::update(who[sa[r]], );
- while(l > L) l--, SGT::update(who[sa[l]], );
- while(r > R) SGT::update(who[sa[r]], -), r--;
- while(l < L) SGT::update(who[sa[l]], -), l++;
- ans[qus[i].id] = SGT::query(numl, numr, , m, );
- }
- for(int i = ; i <= q; i++) printf("%d %d\n", -ans[i].se, ans[i].fi);
- return ;
- }
- /*
- */
Codeforces 666E E - Forensic Examination SA + 莫队 + 线段树的更多相关文章
- 洛谷P3246 序列 [HNOI2016] 莫队/线段树+扫描线
正解:莫队/线段树+扫描线 解题报告: 传送门! 似乎是有两种方法的,,,所以分别港下好了QAQ 第一种,莫队 看到这种询问很多区间之类的就会自然而然地想到莫队趴?然后仔细思考一下,发现复杂度似乎是欧 ...
- 【codeforces 666E】 Forensic Examination
http://codeforces.com/problemset/problem/666/E (题目链接) 题意 给出一个主串$S$,$n$个匹配串编号从$1$到$n$.$m$组询问,每次询问主串的一 ...
- CF 666E Forensic Examination 【SAM 倍增 线段树合并】
CF 666E Forensic Examination 题意: 给出一个串\(s\)和\(n\)个串\(t_i\),\(q\)次询问,每次询问串\(s\)的子串\(s[p_l:p_r]\)在串\(t ...
- CF 666E Forensic Examination——广义后缀自动机+线段树合并
题目:http://codeforces.com/contest/666/problem/E 对模式串建广义后缀自动机,询问的时候把询问子串对应到广义后缀自动机的节点上,就处理了“区间”询问. 还要处 ...
- Manthan, Codefest 16 H. Fibonacci-ish II 大力出奇迹 莫队 线段树 矩阵
H. Fibonacci-ish II 题目连接: http://codeforces.com/contest/633/problem/H Description Yash is finally ti ...
- 【CF633H】Fibonacci-ish II 莫队+线段树
[CF633H]Fibonacci-ish II 题意:给你一个长度为n的序列$a_i$.m个询问,每个询问形如l,r:将[l,r]中的所有$a_i$排序并去重,设得到的新数列为$b_i$,求$b_1 ...
- BZOJ 4129 树上带修莫队+线段树
思路: 可以先做做BZOJ3585 是序列上的mex 考虑莫队的转移 如果当前数字出现过 线段树上把它置成1 对于询问 二分ans 线段树上查 0到ans的和 是不是ans+1 本题就是把它搞到了序列 ...
- [hdoj6483][莫队+线段树/ST]
A Sequence Game Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- [bzoj4358]permu:莫队+线段树/回滚莫队
这道题是几天前水过去的,现在快没印象了,水一发. 首先我们看到它让求解的是最长的值域 连续段长度,很好. 然后就想到了山海经,但但是我还没有做. 然后又想到了很久以前的一次考试的T3旅馆hotel(我 ...
随机推荐
- 【原创】大叔经验分享(39)spark cache unpersist级联操作
问题:spark中如果有两个DataFrame(或者DataSet),DataFrameA依赖DataFrameB,并且两个DataFrame都进行了cache,将DataFrameB unpersi ...
- PID控制器开发笔记之八:带死区的PID控制器的实现
在计算机控制系统中,由于系统特性和计算精度等问题,致使系统偏差总是存在,系统总是频繁动作不能稳定.为了解决这种情况,我们可以引入带死区的PID算法. 1.带死区PID的基本思想 带死区的PID控制算法 ...
- Confluence 6 上传站点图标后重置你的配色方案
当你上传一个站点标识图片后,Confluence 会根据你上传的图片文件自动侦测使用的颜色,并为你设置自动配色方案. 你可以按照上面描述的方法修改色彩配色方案,或者你也可以重置配色方案为默认的配色方案 ...
- 兼容性很好的纯css圆角
<!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...
- React-Native到0.44版本后Navigator 不能用的问题
新升级 到0.46版本以后 Navigator 不能使用报错. 'Navigator is deprecated and has been removed from this package. It ...
- javaScript遍历对象、数组总结
javaScript遍历对象总结 1.使用Object.keys()遍历 返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含Symbol属性). var obj = {'0':'a ...
- select下拉框使用完毕后,重置按钮使其清空
需求描述:select下拉框后边有两个按钮,一个查询,一个重置,点击重置,select会清空之前选择的那个查询条件 解决思路:卧槽,这不so easy 么,用那个jQ封装的trigger函数搞定啊,对 ...
- uva11865 二分流量+最小生成树
uva好题真多 本题用二分法找flow,把流量小于flow的全部筛掉,剩下的边建立最小树形图,如果权值大于c或者不能建图,那么修改二分边界 上代码,觉得最小树形图的代码很优美 /* 题意:给定n个点, ...
- DOBRI
问题 : DOBRI 时间限制: 1 Sec 内存限制: 128 MB 题目描述 给出一个包含N个整数的序列A,定义这个序列A的前缀和数组为SUM数组 ,当SUM数组中的第i个元素等于在i前面的三个 ...
- Ubuntu强制重启后提示emergency mode
起因 win10+Ubuntu16.04双系统,在ubuntu下训练一个卷积网但是显存拙计卡死了,于是手贱强制按下电源开关重启. 现象 重启后从grub进ubuntu,并不进图形化的登录界面,而是提示 ...