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. 今天科普一下 iOS马甲包审核以及常见审核问题

    一.什么是马甲包 马甲包是利用App store 规则漏洞,通过技术手段,多次上架同一款产品的方法.马甲包和主产品包拥有同样的内容和功能,除了icon和应用名称不能完全一致,其他基本一致.    二. ...

  2. gitlab和github区别

    1.概述: github  是一个基于git实现在线代码托管的仓库,向互联网开放,企业版要收钱.gitlab   类似 github,一般用于在企业内搭建git私服,要自己搭环境. 2.GitHub. ...

  3. MYSQL AND OR的联用

    MYSQL中"AND"和"OR"都是条件控制符."AND"是求交集,而"OR"则是求并集,非常多情况下,须要联用它们两个 ...

  4. 为 sublime text3 添加 github 上的插件

    1.CMD+SHIFT+P ---> ADD REPOSITORY 输入 github 上的地址 https://github.com/akira-cn/sublime-gbk 2.CMD+SH ...

  5. 2013夏,iDempiere来了 - v1.0c Installers (Devina LTS Release) 2013-06-27

    怀揣着为中小企业量身定做一整套开源软件解决方案的梦想开始了一个网站的搭建.http://osssme.org/ iDempiere来了 - v1.0c Installers (Devina LTS R ...

  6. docker中批量删除 tag为none的镜像

    添加定时任务,批量删除tag 为none 的镜像  ,释放磁盘空间 [root@weifeng]:~# crontab -l */ * * * /usr/bin/docker rmi `docker ...

  7. Sphinx-简介及原理

    1.Sphinx简介 是一款基于SQL的高性能全文检索引擎(还不支持NoSQL), 主要优点有: 1).创建和重建索引迅速 2).大数据量时检索速度较快 3).为很多脚本语言设计了检索API(如PHP ...

  8. mysql中如何统计某字段里某个字符的个数

    select * from order where length(order_num)-length(replace(order_num,'8','')) = 4

  9. bootstrap 警告

    本章将讲解警告(Alerts)以及Bootstrap所提供的用于警告的class.警告(Alerts)向用户提供了一种定义消息样式的方式.它们为典型的用户操作提供了上下文信息反馈. 您可以为警告框添加 ...

  10. win8安装Visual C++ 2015 build tools闪退解决办法

    win8安装Visual C++ 2015 build tools闪退解决办法 安装Visual Studio 2015闪退问题也同样应用此解决办法. 1.控制面板——添加删除程序——启动关闭wind ...