Codeforces 220B - Little Elephant and Array 离线树状数组
This problem can be solve in simpler O(NsqrtN) solution, but I will describe O(NlogN) one.
We will solve this problem in offline. For each x (0 ≤ x < n) we
should keep all the queries that end in x. Iterate that x from
0 to n - 1. Also we need to keep some array D such
that for current x Dl + Dl + 1 + ... + Dx will
be the answer for query [l;x]. To keep D correct,
before the processing all queries that end in x, we need to update D.
Let t be the current integer in A,
i. e. Ax,
and vector P be the list of indices of previous occurences of t (0-based
numeration of vector). Then, if |P| ≥ t, you need to add 1 to DP[|P| - t],
because this position is now the first (from right) that contains exactly t occurences
of t. After that, if |P| > t,
you need to subtract 2 from DP[|P| - t - 1],
in order to close current interval and cancel previous. Finally, if |P| > t + 1, then you need additionally add 1 to DP[|P| - t - 2] to
cancel previous close of the interval.
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <map>
#include <set>
#include <queue>
using namespace std; #define ls(rt) rt*2
#define rs(rt) rt*2+1
#define ll long long
#define ull unsigned long long
#define rep(i,s,e) for(int i=s;i<e;i++)
#define repe(i,s,e) for(int i=s;i<=e;i++)
#define CL(a,b) memset(a,b,sizeof(a))
#define IN(s) freopen(s,"r",stdin)
#define OUT(s) freopen(s,"w",stdout) const int MAXN = 1e5+100;
int n,m; int a[MAXN],c[MAXN],ans[MAXN];
struct Query
{
int l,r,id;
bool operator < (const Query &t) const {return r<t.r;}
}q[MAXN];
inline int lowbit(int x){return x&(-x);}
void add(int i, int v)
{
while(i<=n)
{
c[i]+=v;
i+=lowbit(i);
}
}
int sum(int x)
{
int ret=0;
while(x>0)
{
ret+=c[x];
x-=lowbit(x);
}
return ret;
} int main()
{
int sz;
while(~scanf("%d%d",&n,&m))
{
vector<int>data[MAXN];
CL(c,0);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&q[i].l,&q[i].r);
q[i].id=i;
}
sort(q+1,q+1+m);
for(int i=1,k=1;i<=n;i++)
{
if(a[i]<=n)
{
data[a[i]].push_back(i);
sz=data[a[i]].size();
if(sz>=a[i])
{
add(data[a[i]][sz-a[i]],1);
if(sz>a[i])add(data[a[i]][sz-a[i]-1],-2);
if(sz>a[i]+1)add(data[a[i]][sz-a[i]-2],1);
}
}
while(q[k].r==i && k<=m)
{
ans[q[k].id]=sum(q[k].r)-sum(q[k].l-1);
k++;
}
} for(int i=1;i<=m;i++)
printf("%d\n",ans[i]); }
return 0;
}
用于调试理解的及及加了凝视的代码
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <map>
#include <set>
#include <queue>
using namespace std; #define ls(rt) rt*2
#define rs(rt) rt*2+1
#define ll long long
#define ull unsigned long long
#define rep(i,s,e) for(int i=s;i<e;i++)
#define repe(i,s,e) for(int i=s;i<=e;i++)
#define CL(a,b) memset(a,b,sizeof(a))
#define IN(s) freopen(s,"r",stdin)
#define OUT(s) freopen(s,"w",stdout) const int MAXN = 1e5+100;
int n,m; int a[MAXN],c[MAXN],ans[MAXN];
struct Query
{
int l,r,id;
bool operator < (const Query &t) const {return r<t.r;}
}q[MAXN];
inline int lowbit(int x){return x&(-x);}
void add(int i, int v)
{
while(i<=n)
{
c[i]+=v;
i+=lowbit(i);
}
}
int sum(int x)
{
int ret=0;
while(x>0)
{
ret+=c[x];
x-=lowbit(x);
}
return ret;
} int main()
{
int sz;
while(~scanf("%d%d",&n,&m))
{
vector<int>data[MAXN];
CL(c,0);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&q[i].l,&q[i].r);
q[i].id=i;
}
sort(q+1,q+1+m);
for(int i=1,k=1;i<=n;i++)
{
if(a[i]<=n)
{
data[a[i]].push_back(i);
sz=data[a[i]].size();
if(sz>=a[i])
{
add(data[a[i]][sz-a[i]],1);//从右往左第a[i]次出现a[i]的位置+1
if(sz>a[i])add(data[a[i]][sz-a[i]-1],-2);
//从右往左第a[i]+1次出现a[i]的位置 -2,
//由于当Sz==a[i]的时候,这个位置已经被加过1。此次读到i的时候。
//从右往左第a[i]次出现a[i]的位置也被+1。
//那么查询第a[i]+1次出现a[i]的位置到i。答案就是-2+1+1=0,
//查询第a[i]次出现a[i]的位置到i,答案就是1
if(sz>a[i]+1)add(data[a[i]][sz-a[i]-2],1);
//从右往左第a[i]+2次出现a[i]的位置 +1,之前被+1-2,所以变成0
//这三行代码维护出来,从当前的i往左数,第a[i]次出现a[i]的位置总是1
//第a[i]+1次出现a[i]的位置总是-1,第a[i]+2及很多其它次的位置总是0,这样以i为右端点的区间的查询结果就都对了
}
}
while(q[k].r==i && k<=m)
{
/////////////
printf("#i=%d#\n",i);
for(int j=0;j<=n;j++)
printf("c[%d]=%d\n",j,c[j]);
//////////////
ans[q[k].id]=sum(q[k].r)-sum(q[k].l-1);
k++;
}
} for(int i=1;i<=m;i++)
printf("%d\n",ans[i]); }
return 0;
}
Codeforces 220B - Little Elephant and Array 离线树状数组的更多相关文章
- Educational Codeforces Round 10 D. Nested Segments 离线树状数组 离散化
D. Nested Segments 题目连接: http://www.codeforces.com/contest/652/problem/D Description You are given n ...
- Codeforces 703D Mishka and Interesting sum 离线+树状数组
链接 Codeforces 703D Mishka and Interesting sum 题意 求区间内数字出现次数为偶数的数的异或和 思路 区间内直接异或的话得到的是出现次数为奇数的异或和,要得到 ...
- CodeForces - 220B Little Elephant and Array (莫队+离散化 / 离线树状数组)
题意:N个数,M个查询,求[Li,Ri]区间内出现次数等于其数值大小的数的个数. 分析:用莫队处理离线问题是一种解决方案.但ai的范围可达到1e9,所以需要离散化预处理.每次区间向外扩的更新的过程中, ...
- Codeforces Round #365 (Div. 2) D - Mishka and Interesting sum(离线树状数组)
http://codeforces.com/contest/703/problem/D 题意: 给出一行数,有m次查询,每次查询输出区间内出现次数为偶数次的数字的异或和. 思路: 这儿利用一下异或和的 ...
- POJ 3416 Crossing --离线+树状数组
题意: 给一些平面上的点,然后给一些查询(x,y),即以(x,y)为原点建立坐标系,一个人拿走第I,III象限的点,另一个人拿II,IV象限的,点不会在任何一个查询的坐标轴上,问每次两人的点数差为多少 ...
- HDU 2852 KiKi's K-Number(离线+树状数组)
题目链接 省赛训练赛上一题,貌似不难啊.当初,没做出.离线+树状数组+二分. #include <cstdio> #include <cstring> #include < ...
- CF #365 (Div. 2) D - Mishka and Interesting sum 离线树状数组
题目链接:CF #365 (Div. 2) D - Mishka and Interesting sum 题意:给出n个数和m个询问,(1 ≤ n, m ≤ 1 000 000) ,问在每个区间里所有 ...
- CF #365 (Div. 2) D - Mishka and Interesting sum 离线树状数组(转)
转载自:http://www.cnblogs.com/icode-girl/p/5744409.html 题目链接:CF #365 (Div. 2) D - Mishka and Interestin ...
- HDU3333 Turing Tree 离线树状数组
题意:统计一段区间内不同的数的和 分析:排序查询区间,离线树状数组 #include <cstdio> #include <cmath> #include <cstrin ...
随机推荐
- (转)SQL流程控制语句学习(一):变量及控制语句种类
1.局部变量 用户自己定义的,称局部变量,以@标识. 作用范围:定义局部变量的批处理.存储过程.触发器和语句块 局部变量的定义: declare @局部变量名 数据类型 注意:变量的类型不能是text ...
- Linq使用GroupBy筛选数据
StringBuilder sb = new StringBuilder(); List<IGrouping<string, modle>> listRepeat = mode ...
- Objective-C 笔记 字符串操作
这次总结下OC里一些对字符串的一些操作. 创建字符串对象时,会创建一个内容不可更改的对象,称为不可变对象.可以使用NSString类处理不可变字符串.你经常需要处理字符串并更改字符串中的字符.例如,可 ...
- css样式-ime-mode text-transform
今天遇到一个新的css样式: ime-mode text-transform 有效小作用 取值:auto : 默认值.不影响ime的状态.与不指定 ime-mode 属性时相同 active : ...
- 关于webApi302跳转的问题
之前会出现"服务器无法在已发送 HTTP 标头之后设置状态"的问题,本地调试不报错,但是上产线就会报错 解决的思路是: var response = Request.CreateR ...
- Selenium2+Python自动化测试实战
本人在网上查找了很多做自动化的教程和实例,偶然的一个机会接触到了selenium,觉得非常好用.后来就在网上查阅各种selenium的教程,但是网上的东西真的是太多了,以至于很多东西参考完后无法系统的 ...
- python爬虫程序
http://blog.csdn.net/pleasecallmewhy/article/details/8922826 此人的博客关于python爬虫程序分析得很好!
- python_基本语法_01
离毕业工作还有几个月,本来想早点去公司实习,无奈gb学校不给放.好吧,既然这样,就学门语言. 参考与 http://www.cnblogs.com/vamei ,我是跟着这位博客牛人的博客教程学的,具 ...
- Linq延迟执行
LINQ中大部分查询运算符都有一个非常重要的特性:延迟执行.这意味着,他们不是在查询创建的时候执行,而是在遍历的时候执行(换句话说,当enumerator的MoveNext方法被调用时).让我们考虑下 ...
- Spark 资源调度及任务调度
1. 资源分配 通过SparkSubmit进行提交应用后,首先会创建Client将应用程序(字节码文件.class)包装成Driver,并将其注册到Master.Master收到Client的注册请 ...