[HEOI2012]采花(树状数组+离线)
2024-08-31 12:42:57
听说这题的所发和HH的项链
很像。
然而那道题我使用莫队写的。。。
这是一个套路,pre数组加升维(在线)。
记录一个\(pre\)数组,\(pre[i]\)代表上一个和i颜色相同的下标。
我们把询问离线,扫一遍\(a\)数组。然后每扫过一个点,就把\(pre[pre[i]]\)这个位置上减1,把\(pre[i]\)加1。然后每一个询问,就输出\([l,r]\)的权值和就行了。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
const int N=2010100;
typedef pair<int,int> p;
vector<p> vec[N];
int n,c,m,pre[N],last[N];
long long tr[N],ans[N];
int lowbit(int x){
return x&-x;
}
void add(int x,int w){
if(x==0)return;
for(int i=x;i<=n;i+=lowbit(i))tr[i]+=w;
}
int getsum(int x){
int tmp=0;
for(int i=x;i;i-=lowbit(i))tmp+=tr[i];
return tmp;
}
int read(){
int sum=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
return sum*f;
}
int main(){
n=read(),c=read(),m=read();
for(int i=1;i<=n;i++){
int a=read();
pre[i]=last[a];
last[a]=i;
}
for(int i=1;i<=m;i++){
int l=read(),r=read();
vec[r].push_back(make_pair(l,i));
}
for(int i=1;i<=n;i++){
add(pre[pre[i]],-1);
add(pre[i],1);
for(int j=0;j<vec[i].size();j++)
ans[vec[i][j].second]=getsum(i)-getsum(vec[i][j].first-1);
}
for(int i=1;i<=m;i++)printf("%lld\n",ans[i]);
return 0;
}
最新文章
- Birt使用总结
- 【转】C#多线程
- c++内存分布
- Python 中 sqlite3的使用
- Stanford机器学习---第九讲. 聚类
- [转]SVN-版本控制软件
- Centos 6.5编译安装Nginx+php+Mysql
- C#向文件写、读数据
- NYOJ306 走迷宫(dfs+二分搜索)
- ashx页面中context.Session[";xxx";]获取不到值的解决办法
- 重启OpenStack服务步骤
- SecureCRT使用本地公钥 SSH 免密码登录Linux
- django-simple-captcha 验证码插件
- 多选下拉框带搜索(aps.net)
- PHP之文件上传
- 07: Django 使用ldap登录、注销等
- mac指令备忘
- C#设计模式泛型注入
- nancyfx中的静态内容文件夹
- MongoDB 学习(一)安装配置和简单应用