http://codeforces.com/contest/813/problem/E

题目大意:

给出长度为n的数组和k,  大小是1e5级别。

要求在线询问区间[l, r]权值,  权值定义为对于所有不同元素x在区间出现的次数和, 如果x出现次数>k, 那么按k算。

重要转换: 考虑一个区间[L, R]的某个数A[i], 它对答案有贡献 当且仅当 它前面与他权值相同的数中第k个数的位置(记为B[i]) < L

预处理B[], 每次询问就转化为 区间[L, R]中有多少个B[i] < L

可以用主席树 或者 分块解决。

也可以用此题的方法求区间不同元素个数, 其实就是k = 1的情况。

主席树代码:

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
using namespace std; typedef long long ll; #define N 100050
const int INF = << ;
const double pi = acos(-); int pt;
int a[N], b[N], root[N], lc[N * ], rc[N * ], cnt[N * ];
vector<int> lis[N]; int Add(int y, int l, int r, int v)
{
int x = ++pt;
cnt[x] = cnt[y] + ;
if (l < r)
{
int mid = (l + r) >> ;
if (v <= mid)
{
rc[x] = rc[y];
lc[x] = Add(lc[y], l, mid, v);
}
else
{
lc[x] = lc[y];
rc[x] = Add(rc[y], mid + , r, v);
}
}
return x;
} int Query(int x, int y, int L, int R, int l, int r)
{
//cout << L <<" " << R << " " << cnt[x] << " " << cnt[y] << endl;
if (l > R || r < L) return ;
if (l <= L && r >= R) return cnt[x] - cnt[y]; int Mid = (L + R) >> ;
return Query(lc[x], lc[y], L, Mid, l, r) + Query(rc[x], rc[y], Mid + , R, l, r);
} int main()
{
//freopen("in.in", "r", stdin);
//freopen("out.out", "w", stdout); int n, k, Q, lastans = , l, r;
scanf("%d %d", &n, &k);
for (int i = ; i <= n; ++i) scanf("%d", &a[i]), lis[a[i]].push_back(i); for (int i = ; i <= ; ++i)
{
if (lis[i].size() <= k) continue;
for (int j = k; j < lis[i].size(); ++j) b[lis[i][j]] = lis[i][j - k];
} root[] = ++pt;
for (int i = ; i <= n; ++i) root[i] = Add(root[i - ], , n, b[i]); scanf("%d", &Q);
while (Q--)
{
scanf("%d %d", &l, &r);
l = (l + lastans) % n + ;
r = (r + lastans) % n + ;
if (l > r) swap(l, r);
lastans = Query(root[r], root[l - ], , n, , l - );
printf("%d\n", lastans);
} return ;
}

分块代码:

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
using namespace std; typedef long long ll; #define N 100050
const int INF = << ;
const double pi = acos(-); int pt;
int a[N], b[N], id[N], dp[][N];
int bl[], br[];
vector<int> lis[N]; int main()
{
//freopen("in.in", "r", stdin);
//freopen("out.out", "w", stdout); int n, k, Q, lastans = , l, r;
scanf("%d %d", &n, &k);
for (int i = ; i <= n; ++i) scanf("%d", &a[i]), lis[a[i]].push_back(i); for (int i = ; i <= ; ++i)
{
if (lis[i].size() <= k) continue;
for (int j = k; j < lis[i].size(); ++j) b[lis[i][j]] = lis[i][j - k];
} int block = (int)sqrt(n + ); for (int i = ; ; ++i)
{
l = (i - ) * block + ;
r = min(n, l + block - );
bl[i] = l, br[i] = r;
for (int j = l; j <= r; ++j) dp[i][b[j]]++, id[j] = i;
for (int j = ; j <= ; ++j) dp[i][j] += dp[i][j - ];
if (r == n) break;
} scanf("%d", &Q);
while (Q--)
{
scanf("%d %d", &l, &r);
l = (l + lastans) % n + ;
r = (r + lastans) % n + ;
if (l > r) swap(l, r); int res = ;
if (id[l] == id[r])
{
for (int i = l; i <= r; ++i)
res += b[i] < l;
}
else
{
for (int i = l; i <= br[id[l]]; ++i) res += b[i] < l;
for (int i = bl[id[r]]; i <= r; ++i) res += b[i] < l;
for (int i = id[l] + ; i <= id[r] - ; ++i) res += dp[i][l - ];
}
printf("%d\n", res);
lastans = res;
} return ;
}

Educational Codeforces Round 22 E. Army Creation 主席树 或 分块的更多相关文章

  1. Educational Codeforces Round 22 E. Army Creation

    Educational Codeforces Round 22 E. Army Creation 题意:求区间[L,R]内数字次数不超过k次的这些数字的数量的和 思路:和求区间内不同数字的数量类似,由 ...

  2. Educational Codeforces Round 22 E. Army Creation(分块好题)

    E. Army Creation time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  3. [Educational Codeforces Round#22]

    来自FallDream的博客,未经允许,请勿转载,谢谢. 晚上去clj博客逛来逛去很开心,突然同学提醒了一下,发现cf已经开始40分钟了,慌的一B,从B题开始写,写完了B到E最后收掉了A,结果太着急B ...

  4. Educational Codeforces Round 22 补题 CF 813 A-F

    A The Contest 直接粗暴贪心 略过 #include<bits/stdc++.h> using namespace std; int main() {//freopen(&qu ...

  5. Educational Codeforces Round 22.B 暴力

    B. The Golden Age time limit per test 1 second memory limit per test 256 megabytes input standard in ...

  6. Educational Codeforces Round 22 B. The Golden Age(暴力)

    题目链接:http://codeforces.com/contest/813/problem/B 题意:就是有一个数叫做不幸运数,满足题目的 n = x^a + y^b,现在给你一个区间[l,r],让 ...

  7. 【Educational Codeforces Round 22】

    又打了一场EDU,感觉这场比23难多了啊…… 艹还是我太弱了. A. 随便贪心一下. #include<bits/stdc++.h> using namespace std; ,ans=- ...

  8. CF Educational Codeforces Round 10 D. Nested Segments 离散化+树状数组

    题目链接:http://codeforces.com/problemset/problem/652/D 大意:给若干个线段,保证线段端点不重合,问每个线段内部包含了多少个线段. 方法是对所有线段的端点 ...

  9. Educational Codeforces Round 12 E. Beautiful Subarrays 字典树

    E. Beautiful Subarrays 题目连接: http://www.codeforces.com/contest/665/problem/E Description One day, ZS ...

随机推荐

  1. springMVC 头像裁剪上传并等比压

    第一次写头像裁剪上传,原本想着直接本地预览裁剪再上传,可是时间有限,jquery.jcrop貌似并没有对 假设是ie下图片预览效果是滤镜做的  做出对应处理,也没有时间去改;仅仅好将就一下先把图片上传 ...

  2. c# 句柄数不断攀升的解决方案

    句柄只是用来标识应用程序中的不同对象和同类中的不同的实例的一个数字,通常情况下,句柄值对普通用户毫无用处,但是句柄数量却可以间接反映出一个程序里产生的对象实例的多少.句柄数越多,代表程序里new 出来 ...

  3. VS报表图解《一》---菜鸟版

    与原先的开发环境VB.EXE不同VS2013自带了报表控件ReportViewer能够内部实现报表的设计,本文主要通过绑定数据集来实现报表的显示 1.加入:reportviewer控件,当将控件显示在 ...

  4. php遍历文件夹代码实现

    <?php //遍历文件夹 function my_scandir($dir){ $files = array(); if (is_dir($dir)){ if($handle = opendi ...

  5. Visual Studio 2015下编译zmq项目下其他项目踩进的项目引用坑

    PS.在之前的一篇文章中介绍了如何用Visual Studio 2015编译zmq,在编译同解决方案中除了libzmq之外的项目例如inproc_thr时会报错误,具如下: Severity Code ...

  6. 采集Snoopy.class.php

    <?php /************************************************* Snoopy - the PHP net client Author: Mont ...

  7. Linux yum操作无效的解决方法

    1.没网,试着:ping www.baidu.com 如果显示没有连接的话,就说明没网,也就无法使用yum 命令. 2.ping通了的话,还是是用不了yum命令,说明是yum镜像没有了,那么就得下载一 ...

  8. 阿里云slb实现多域名https

    刚开始接锅,没注意原来站点的https配置在slb上,在服务器上配置一顿操作猛如虎,细细检查一遍,感觉良好,一测试发现不对劲,检查发现原来https配置在阿里云slb上,阿里云还是做得不错的 ,但是现 ...

  9. Atom打开报错:"Cannot load the system dictionary for zh-CN"

    1. 问题描述 最近每次使用atom打开文件,总是报错"Cannot load the system dictionary for zh-CN" 2. 解决方法 File --&g ...

  10. blender, fbx导入blender进行编辑

    fbx文件导入blender后,直接点下面Object Mode弹不出下拉菜单,从而无法进入Edit Mode.解法是先点一下右边Scene层级列表中的Sphere节点,将其选中,然后再点下面的Obj ...