1. OTZ做出题目的神犇。。断断续续改完了在这里存一下思路吧
  2.  
  3. A题:第K大区间
    题意:
    定义一个区间的值为其众数出现的次数
    现给出n个数,求将所有区间的值排序后,第K大的值为多少。
  4.  
  5. 分析:
    二分答案mid,任务就是判定有多少个区间的众数≥mid
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. typedef long long ll;
  6.  
  7. const int maxn = 100010;
  8.  
  9. int n, A[maxn], c[maxn], cnt[maxn], mx, tmp[maxn];
  10. ll k;
  11.  
  12. void Add(int x){
  13. cnt[c[x]] --;
  14. c[x] ++;
  15. cnt[c[x]] ++;
  16. mx = max(mx, c[x]);
  17. }
  18.  
  19. void Del(int x){
  20. cnt[c[x]] --;
  21. c[x] --;
  22. cnt[c[x]] ++;
  23. while(!cnt[mx])mx --;
  24. }
  25.  
  26. int check(int x){
  27. ll ans = 0, l = 1; mx = 0;
  28. memset(cnt, 0, sizeof cnt);
  29. memset(c, 0, sizeof c);
  30. cnt[0] = n;
  31. for(int i = 1; i <= n; i ++){
  32. Add(A[i]);
  33. while(true){
  34. Del(A[l]);
  35. if(mx < x) {Add(A[l]); break;}
  36. l ++;
  37. }
  38. if(mx >= x) ans += l;
  39. }
  40. return ans >= k;
  41. }
  42.  
  43. int main(){
  44. scanf("%d%d", &n, &k);
  45. for(int i = 1; i <= n; i ++){
  46. scanf("%d", &A[i]);
  47. tmp[i] = A[i];
  48. }
  49. sort(tmp+1, tmp+1+n);
  50. int p = unique(tmp+1, tmp+1+n) - tmp - 1;
  51. for(int i = 1; i <= n; i ++)
  52. A[i] = lower_bound(tmp+1, tmp+1+p, A[i]) - tmp;
  53. int l = 1, r = n+1;
  54. while(l < r){
  55. int mid = l + (r - l + 1) / 2;
  56. if(check(mid))l = mid;
  57. else r = mid - 1;
  58. }
  59. printf("%d\n", l);
  60. return 0;
  61. }
  1.  

  

  1.  
  1.  
  1. B题戳这里
    C题:逛街
  2.  
  3. 分析:
    对于喜欢的店的个数一定要大于等于k,这个可以用一个堆来贪心,维护堆中的元素等于k个,对于其他的离散化一下扔进线段树(splay也不介意,但是好像会t)
    然后在线段树上二分
    注意val有负值a。。然后不能加a
  1. #include <bits/stdc++.h>
  2. #define maxn 200010
  3. using namespace std;
  4. typedef long long ll;
  5. int n, T, k, root, smz;
  6.  
  7. int A[maxn], B[maxn], C[maxn];
  8. long long sum[maxn];
  9.  
  10. priority_queue<pair<ll, int> > Q;
  11.  
  12. int b[maxn];
  13.  
  14. struct Hash{
  15. int id, p;
  16. ll val;
  17. bool operator<(const Hash& k)const{return val < k.val;}
  18. }h[maxn];
  19.  
  20. bool cmp(const Hash& a, const Hash& b){return a.p < b.p;}
  21.  
  22. struct Node{
  23. int l, r, size; ll sum;
  24. }t[maxn << 2];
  25. #define lc id<<1
  26. #define rc id<<1|1
  27. void build(int id, int l, int r){
  28. t[id].l = l, t[id].r = r;
  29. if(l == r)return;
  30. int mid = l+r >> 1;
  31. build(lc, l, mid);
  32. build(rc, mid+1, r);
  33. }
  34.  
  35. void pushup(int id){
  36. t[id].sum = t[lc].sum + t[rc].sum;
  37. t[id].size = t[lc].size + t[rc].size;
  38. }
  39.  
  40. void update(int id, int pos, ll val){
  41. if(val < 0)return;
  42. if(t[id].l == t[id].r){
  43. t[id].sum = val;
  44. t[id].size ++;
  45. return;
  46. }
  47. int mid = t[id].l + t[id].r >> 1;
  48. if(pos <= mid)update(lc, pos, val);
  49. else update(rc, pos, val);
  50. pushup(id);
  51. }
  52.  
  53. int ask(int id, ll T){
  54. if(t[id].l == t[id].r)return min(t[id].size, (int)(T >= t[id].sum));
  55. if(T >= t[lc].sum)return t[lc].size + ask(rc, T - t[lc].sum);
  56. return ask(lc, T);
  57. }
  58.  
  59. int vis[maxn];
  60.  
  61. int main(){
  62. scanf("%d%d%d", &n, &T, &k);
  63. for(int i = 1; i <= n; i ++)scanf("%d", &A[i]);
  64. for(int i = 1; i <= n; i ++)scanf("%d", &B[i]), h[i].val = B[i], h[i].p = i;
  65. for(int i = 1; i <= n; i ++)scanf("%d", &C[i]);
  66.  
  67. sort(h+1, h+1+n);
  68.  
  69. for(int i = 1; i <= n; i ++)
  70. h[i].id = i;
  71. sort(h+1, h+1+n, cmp);
  72. for(int i = 1; i <= n; i ++)b[i] = h[i].id;
  73. build(1, 1, n);
  74. int ans = 0;
  75. ll Sum = 0;
  76. for(int i = 1; i <= n; i ++){
  77. if(C[i]){
  78. if(Q.size() < k)Q.push(make_pair(B[i], i)), Sum += B[i];
  79. else if(!Q.empty() && (Q.size() == k && B[i] < Q.top().first)){
  80. ll t = Q.top().first;
  81. int t1 = Q.top().second;Q.pop();
  82. Q.push(make_pair(B[i], i));Sum = Sum - t + B[i];
  83. update(1, b[t1], t);
  84. }else update(1, b[i], B[i]);
  85. }
  86. else update(1, b[i], B[i]);
  87. if(Q.size() >= k && Sum + A[i] <= T)ans = max(ans, k + ask(1, T - Sum - A[i]));
  88. }
  89. if(ans < k)puts("-1");
  90. else printf("%d\n", ans);
  91. return 0;
  92. }
  1.  

  

  1.  
  1. D题:Rikka with Sequences
  1. 题目大意:给定一个序列,有更改操作,每次查询一段区间的历史区间和最小值。
  1. n, m 10^5, Ai 10^9
  1. 分析:
  1. 这个在线好难做a。所以就要离线la。所以就要用KD-tree啦。(QAQ)
    对于每一个操作我们可以计算它对询问的贡献。把一个询问看成二维平面上的一个点(l, r),每一次操作都是将(pos, pos)左上角(l <= pos, r >= pos)的询问更改一下,通过打标记来实现历史最小值的询问。时光倒流,如果是每次给一个位置添加数字,询问历史最小值是个经典问题la
    一定不要忘记pushdown。。。一定不要忘记mn[i]和mx[i]
  1. #include <bits/stdc++.h>
  2. #define maxn 100010
  3. using namespace std;
  4.  
  5. typedef long long ll;
  6.  
  7. const int inf = 0x7fffffff;
  8.  
  9. int n, m, dfs_clock, D;
  10. //----------------------KD-tree--------------------------//
  11. struct Node{
  12. int l, r, mn[2], mx[2], d[2], id;
  13. ll sum, add, ans, Minadd;
  14. int& operator[](const int& k){return d[k];}
  15. bool operator<(Node k)const{return d[D] < k[D];}
  16. Node(int x = 0, int y = 0, int i = 0, ll s = 0){
  17. sum = ans = s, id = i;
  18. mn[0] = mx[0] = d[0] = x;
  19. mn[1] = mx[1] = d[1] = y;
  20. l = r = add = Minadd = 0;
  21. }
  22. }t[maxn], dfn[maxn], P;
  23. int tot, root;
  24.  
  25. void update(int o){
  26. for(int i = 0; i < 2; i ++){
  27. t[o].mn[i] = t[o].mx[i] = t[o][i];
  28. if(t[o].l){
  29. t[o].mn[i] = min(t[o].mn[i], t[t[o].l].mn[i]);
  30. t[o].mx[i] = max(t[o].mx[i], t[t[o].l].mx[i]);
  31. }
  32. if(t[o].r){
  33. t[o].mn[i] = min(t[o].mn[i], t[t[o].r].mn[i]);
  34. t[o].mx[i] = max(t[o].mx[i], t[t[o].r].mx[i]);
  35. }
  36. }
  37. }
  38.  
  39. int Newnode(){
  40. t[++ tot] = P;
  41. return tot;
  42. }
  43.  
  44. inline void Down1(int o, ll val){
  45. if(!o)return;
  46. t[o].ans = min(t[o].ans, t[o].sum + val);
  47. t[o].Minadd = min(t[o].Minadd, t[o].add + val);
  48. }
  49.  
  50. inline void Down2(int o, ll val){
  51. if(!o)return;
  52. t[o].ans = min(t[o].ans, t[o].sum += val);
  53. t[o].Minadd = min(t[o].Minadd, t[o].add += val);
  54. }
  55.  
  56. inline void pushdown(int o){
  57. if(t[o].Minadd){
  58. Down1(t[o].l, t[o].Minadd), Down1(t[o].r, t[o].Minadd);
  59. t[o].Minadd = 0;
  60. }
  61.  
  62. if(t[o].add){
  63. Down2(t[o].l, t[o].add), Down2(t[o].r, t[o].add);
  64. t[o].add = 0;
  65. }
  66. }
  67.  
  68. void Modify(int o, int pos, ll val){
  69. pushdown(o);
  70. if(t[o].mx[0] <= pos && t[o].mn[1] >= pos) {Down2(o, val); return;}
  71. if(t[o][0] <= pos && t[o][1] >= pos)t[o].sum += val, t[o].ans = min(t[o].ans, t[o].sum);
  72. if(t[o].l && t[t[o].l].mn[0] <= pos && t[t[o].l].mx[1] >= pos)Modify(t[o].l, pos, val);
  73. if(t[o].r && t[t[o].r].mn[0] <= pos && t[t[o].r].mx[1] >= pos)Modify(t[o].r, pos, val);
  74. }
  75.  
  76. void Insert(int o, int type){
  77. pushdown(o), D = type;
  78. if(P < t[o]){
  79. if(t[o].l)Insert(t[o].l, type^1);
  80. else t[o].l = Newnode();
  81. }
  82. else{
  83. if(t[o].r)Insert(t[o].r, type^1);
  84. else t[o].r = Newnode();
  85. }
  86. update(o);
  87. }
  88.  
  89. ll ans[maxn];
  90. void dfs(int o){
  91. pushdown(o);
  92. dfn[++ dfs_clock] = t[o];
  93. ans[t[o].id] = t[o].ans;
  94. if(t[o].l)dfs(t[o].l);
  95. if(t[o].r)dfs(t[o].r);
  96. }
  97.  
  98. int build(int l, int r, int type){
  99. if(l > r)return 0; D = type;
  100. int mid = l + r >> 1;
  101. nth_element(dfn+l, dfn+mid, dfn+r+1);
  102. t[mid] = dfn[mid];
  103. t[mid].l = build(l, mid-1, type^1);
  104. t[mid].r = build(mid+1, r, type^1);
  105. update(mid); return mid;
  106. }
  107.  
  108. //----------------------query---------------------------//
  109. int tp[maxn], l[maxn], r[maxn];
  110. //----------------------BIT-----------------------------//
  111. ll A[maxn], Bit[maxn];
  112. #define lowbit(i) i&(~i+1)
  113. void add(int pos, ll val){
  114. for(int i = pos; i <= n; i += lowbit(i))
  115. Bit[i] += val;
  116. }
  117. ll ask(int pos){
  118. if(!pos)return 0;ll ret = 0;
  119. for(int i = pos; i; i -= lowbit(i))
  120. ret += Bit[i];
  121. return ret;
  122. }
  123. //----------------------solve---------------------------//
  124. int main(){
  125. root = Newnode();
  126. t[root].mn[0] = t[root].mn[1] = inf;
  127. t[root].mx[0] = t[root].mx[1] = -inf;
  128. scanf("%d%d", &n, &m);
  129. for(int i = 1; i <= n; i ++)
  130. scanf("%lld", &A[i]), add(i, A[i]);
  131. for(int i = 1; i <= m; i ++){
  132. scanf("%d%d%d", &tp[i], &l[i], &r[i]);
  133. if(tp[i] == 1){
  134. r[i] -= A[l[i]];//增量
  135. A[l[i]] += r[i];
  136. add(l[i], r[i]);
  137. }
  138. }
  139.  
  140. int Buf = 2000;
  141. for(int i = m; i >= 1; i --){
  142. if(tp[i] == 1){
  143. add(l[i], -r[i]);
  144. Modify(root, l[i], -r[i]);
  145. }
  146. else{
  147. P = Node(l[i], r[i], i, ask(r[i]) - ask(l[i]-1));
  148. Insert(root, 0);
  149. }
  150. if(i % Buf == 0)dfs_clock = 0, dfs(root), root = build(1, dfs_clock, 0);
  151. }
  152.  
  153. dfs_clock = 0, dfs(root);
  154. for(int i = 1; i <= m; i ++)
  155. if(tp[i] == 2)printf("%lld\n", ans[i]);
  156. return 0;
  157. }
  1.  

  

  1.  
  1. E题:小ZTire
  2.  
  3. 广义后缀自动机。倍增找到位置输出parent树中子树节点个数
  1. #include <bits/stdc++.h>
  2. #define maxn 2000010
  3. using namespace std;
  4.  
  5. struct Node{int len, link, nxt[26];}st[maxn];
  6.  
  7. int root, size, last;
  8.  
  9. int s[maxn];
  10.  
  11. void init(){
  12. root = size = last = 0;
  13. st[root].len = 0;
  14. st[root].link = -1;
  15. }
  16.  
  17. void Extend(char ch){
  18. int c = ch - 'a', p = last, q = st[p].nxt[c];
  19. if(q){
  20. if(st[q].len == st[p].len + 1)
  21. last = q;
  22. else{
  23. int clone = ++ size;
  24. st[clone] = st[q];
  25. st[clone].len = st[p].len + 1;
  26. for(; ~p && st[p].nxt[c] == q; p = st[p].link)
  27. st[p].nxt[c] = clone;
  28. st[q].link = clone;
  29. last = clone;
  30. }
  31. }
  32. else{
  33. int cur = ++ size;
  34. st[cur].len = st[p].len + 1;
  35. for(; ~p && !st[p].nxt[c]; p = st[p].link)
  36. st[p].nxt[c] = cur;
  37. if(p == -1)
  38. st[cur].link = root;
  39. else{
  40. q = st[p].nxt[c];
  41. if(st[q].len == st[p].len + 1)
  42. st[cur].link = q;
  43. else{
  44. int clone = ++ size;
  45. st[clone] = st[q];
  46. st[clone].len = st[p].len + 1;
  47. for(; ~p && st[p].nxt[c] == q; p = st[p].link)
  48. st[p].nxt[c] = clone;
  49. st[q].link = st[cur].link = clone;
  50. }
  51. }
  52. last = cur;
  53. }
  54. s[last] = 1;
  55. }
  56.  
  57. int n;
  58.  
  59. char c[maxn];
  60.  
  61. int anc[maxn][22];
  62.  
  63. int t[maxn], w[maxn];
  64.  
  65. void pre_anc(){
  66. for(int i = 1; i <= size; i ++)w[st[i].len] ++;
  67. for(int i = 1; i <= size; i ++)w[i] += w[i-1];
  68. for(int i = 1; i <= size; i ++)t[w[st[i].len] --] = i;
  69. for(int i = size; i >= 1; i --)s[st[t[i]].link] += s[t[i]];
  70.  
  71. memset(anc, -1, sizeof anc);
  72. for(int i = 1; i <= size; i ++)
  73. anc[i][0] = st[i].link;
  74. for(int j = 1; 1 << j <= size; j ++){
  75. for(int i = 1; i <= size; i ++){
  76. int a = anc[i][j-1];
  77. if(~a)anc[i][j] = anc[a][j-1];
  78. }
  79. }
  80. }
  81.  
  82. vector<int>V[100010];
  83.  
  84. int ask_pos(int r, int len){
  85. int now = r;
  86. for(int i = 21; i >= 0; i --){
  87. int t = anc[now][i];
  88. if(t == -1)continue;
  89. if(st[t].len >= len)now = t;
  90. }
  91. return now;
  92. }
  93.  
  94. int main(){
  95. init();
  96. scanf("%d", &n);
  97. for(int i = 1; i <= n; i ++){
  98. scanf("%s", c+1);
  99. int N = strlen(c+1);
  100. last = root;
  101. for(int j = 1; j <= N; j ++){
  102. Extend(c[j]);
  103. V[i].push_back(last);
  104. }
  105. }
  106.  
  107. pre_anc();
  108.  
  109. int m, u, v, d;
  110. scanf("%d", &m);
  111. for(int i = 1; i <= m; i ++){
  112. scanf("%d%d%d", &u, &v, &d);
  113. printf("%d\n", s[ask_pos(V[u][d-1], d-v+1)]);
  114. }
  115. return 0;
  116. }
  1.  
  1.  

  

  1.  

51NOD 算法马拉松12的更多相关文章

  1. 51nod算法马拉松12

    A 第K大区间 不妨考虑二分答案x,则问题转化成计算有多少个区间满足众数出现的次数>=x. 那么这个问题我们使用滑动窗口,枚举右端点,则左端点肯定单调递增,然后维护一个简单的数组就能资瓷添加元素 ...

  2. 51Nod 算法马拉松12 Rikka with sequences

    当时做比赛的时候听说过这类用KD_Tree维护的数据结构题 然后知道是KD_Tree,然而并不知道怎么写QAQ 比赛完了之后%了一发代码 其基本思路是这样的: 1.首先我们把询问[L,R]看成二维平面 ...

  3. 51Nod 算法马拉松12 移数博弈

    点进去发现并不是博弈QAQ 一开始考虑单调队列什么乱七八糟的发现根本做不出来 (没错我一直在想枚举最大值求次大值QAQ 不妨换个思路: 我们考虑枚举次大值求最大值 设当前为now, 设now之前第一个 ...

  4. 51NOD 算法马拉松8

    题目戳这里:51NOD算法马拉松8 某天晚上kpm在玩OSU!之余让我看一下B题...然后我就被坑进了51Nod... A.还是01串 水题..怎么乱写应该都可以.记个前缀和然后枚举就行了.时间复杂度 ...

  5. 51nod 算法马拉松 34 Problem D 区间求和2 (FFT加速卷积)

    题目链接  51nod 算法马拉松 34  Problem D 在这个题中$2$这个质数比较特殊,所以我们先特判$2$的情况,然后仅考虑大于等于$3$的奇数即可. 首先考虑任意一个点对$(i, j)$ ...

  6. 随便玩玩系列之一:SPOJ-RNG+51nod 算法马拉松17F+51nod 1034 骨牌覆盖v3

    先说说前面的SPOJ-RNG吧,题意就是给n个数,x1,x2,...,xn 每次可以生成[-x1,x1]范围的浮点数,把n次这种操作生成的数之和加起来,为s,求s在[A,B]内的概率 连续形的概率 假 ...

  7. 51Nod 算法马拉松21(迎新年)

    这次打算法马拉松是在星期五的晚上,发挥还算正常(废话,剩下的题都不会= =). 讲讲比赛经过吧. 8:00准时发题,拿到之后第一时间开始读. A配对,看上去像是二分图最大权匹配,一看范围吓傻了,先跳过 ...

  8. 51Nod 算法马拉松15 记一次悲壮而又开心的骗分比赛

    OwO 故事的起源大概是zcg前天发现51Nod晚上有场马拉松,然后他就很开心的过去打了 神奇的故事就开始了: 晚上的时候我当时貌似正在写线段树?然后看见zcg一脸激动告诉我第一题有九个点直接输出B就 ...

  9. 51Nod 算法马拉松23 开黑记

    惨啊……虽然开了半天黑,但是还是被dalao们踩了…… 第二次开黑,还是被卡在rank20了,我好菜啊……= = 写一写比赛经过吧…… 看到题之后习惯性都打开,A~D看上去似乎并没有什么思路,F应该是 ...

随机推荐

  1. zb的生日

    http://acm.nyist.net/JudgeOnline/problem.php?pid=325 zb的生日 时间限制:3000 ms  |  内存限制:65535 KB 难度:2   描述 ...

  2. 题目1006:ZOJ问题

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:13212 解决:2214 题目描述: 对给定的字符串(只包含'z','o','j'三种字符),判断他是否能AC. 是否AC的规则如下:1. ...

  3. 硬盘安装ubuntu注意事项

    按照教程 http://teliute.org/linux/Ubsetup/jichu3/jichu3.html 安装64位ubuntu的时候,因为64位版本的iso安装包里没有vmlinuz文件,而 ...

  4. 重新编译安装gcc-4.1.2(gcc版本降级)之TFS安装

    wget http://gcc.parentingamerica.com/releases/gcc-4.1.2/gcc-4.1.2.tar.gz tar -zxfv gcc-4.1.2.tar.gz ...

  5. 工作中常用shell之ssh登陆不用输入"yes"

    ip="192.168.5.166"ssh $ip -o StrictHostKeyChecking=no           //ssh登陆不用输入"yes" ...

  6. iOS 中通过使用Google API获得Google服务

    最近使用了google drive这个云存储,官方指导网址为 https://developers.google.com/drive/ios/ . 官方库代码网址为 http://code.googl ...

  7. 【python】一个简单的贪婪爬虫

    这个爬虫的作用是,对于一个给定的url,查找页面里面所有的url连接并依次贪婪爬取 主要需要注意的地方: 1.lxml.html.iterlinks()  可以实现对页面所有url的查找 2.获取页面 ...

  8. August 4th, 2016, Week 32nd, Thursday

    How does the world look through your eyes? 你眼中的世界是什么样的呢? This morning I saw a girl that is just the ...

  9. weblogic 安装和部署项目(原创)

    1.下载weblogic(含破解文件,土豪请支持正版,谢谢!) 2.安装如下图: 3.新建domain 4.打开weblogic Console 5.开始部署项目 6.部署成功

  10. Flesch Reading Ease (poj 3371)

    题意: 给出一篇规范的文章,求其 句子数.单词数 和 音节数把这3个值代入题目给出的公式,输出其结果,保留2位小数. 标记单词分隔符: 逗号(,) 和 空格( ) 句子分隔符:句号(.) 问号(?) ...