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. profile_oracle设置某用户password永只是期

    原创作品.出自 "深蓝的blog" 博客,深蓝的blog:http://blog.csdn.net/huangyanlong/article/details/46888139 or ...

  2. 重构wm_concat,采用clob做为存储容器

    --Type CREATE OR REPLACE TYPE zh_concat_im AUTHID CURRENT_USER AS OBJECT ( CURR_STR clob, STATIC FUN ...

  3. 无埋点数据收集和adb monkey测试屏蔽通知栏

    简单记录百度移动统计android无埋点sdk使用和monkey测试屏蔽通知栏的问题 1.无埋点sdk使用 很简单,下载完sdk后导入到项目中 , 参考sdk文档进行就可以了,个人觉得比友盟还简单,几 ...

  4. NestedScrollView嵌套RecyclerView

    天气渐寒,然学习不可懈怠,记录一下使用NestedScrollView嵌套RecyclerView的两个问题,以后遇到可以来这里温故. 应该说在MD中,RecyclerView代替了ListView, ...

  5. 【VBA编程】04.使用自定义数据类型

    使用自定义数据类型存储输入数据,并通过弹出窗口展示 [代码区域] Type lianxiren ' name As String Sex As String End Type Sub aa() Dim ...

  6. 【WEB】jQuery获取页面回滚或跳转事件

    1.效果: 2.Jquery: //记得引入jquery.min.js <script type="text/javascript"> $(function(){ wi ...

  7. zabbix_get :command not found 解决办法

    zabbix_get 找不到命令是因为没有安装上zabbix_get ,解决办法: 1.yum list all |grep zabbix 返回一个列表,表中出现 zabbix-get.x86_84 ...

  8. Python-代码对象

    可调用的对象是python执行环境中最重要的部分,python语句,赋值,表达式,模块等,这些 对象只是构成可执行代码块的拼图的很少的一部分,而这些代码块被称为代码对象.   每个可调用的对象的核心都 ...

  9. EMQ(TLS)

    1.TLS证书验证 为了保障安全.我们常常会使用HTTPS来保障请求不被篡改,作为MQTT使用TLS加密的方式来保障传输安全 EMQ默认使用的TLS加密的端口是8883端口,默认证书在EMQ目录下et ...

  10. AssionShop开源B2C电子商务系统-(一)用例图(转载)

    这篇文章,将有实质的进展.先把大体的需求整理了一份用例图,自认为粒度做的已经很细了,再细就没法搞了.我还是坚信一个原则:自己业余搞的东西千万不要 想一口吃个胖子,这样很容易项目就搞流产了~,废话不多说 ...