BZOJ 3236: [Ahoi2013]作业
2016-03-12 21:33
288 查看
BZOJ 3236: [Ahoi2013]作业
标签(空格分隔): OI-BZOJ OI-莫队 OI-分块 OI-树状数组Time Limit: 100 Sec
Memory Limit: 512 MB
Description
![](http://www.lydsy.com/JudgeOnline/upload/201306/1%282%29.jpg)
Input
![](http://www.lydsy.com/JudgeOnline/upload/201306/2.jpg)
Output
![](http://www.lydsy.com/JudgeOnline/upload/201306/3.jpg)
Sample Input
3 4
1 2 2
1 2 1 3
1 2 1 1
1 3 1 3
2 3 2 3
Sample Output
2 2
1 1
3 2
2 1
HINT
N=100000,M=1000000
Solution
莫队裸题我偷了个懒,用树状数组统计出现次数,稍微优化了一下常数76s过去了。
复杂度\(O(n*\sqrt{n}*log_2n)\)
统计某个区间内的数字个数的时候可以使用分块,修改\(O(1)\)
查询的时候\(O(\sqrt{n})\)总复杂度\(O((n+m)*\sqrt{n})\)
Code
#include<iostream> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<algorithm> #include<queue> #include<set> #include<map> #include<bitset> #include<vector> using namespace std; #define PA pair<int,int> int read() { int s=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){s=(s<<1)+(s<<3)+ch-'0';ch=getchar();} return s*f; } //smile please struct que { int l,r,a,b,h; }q[1000005]; int n,m,L; int t1[100005],t2[100005],a[100005],b[100005]; bool cmp(const que &a,const que &b) {return a.l/L<b.l/L||(a.l/L==b.l/L&&a.r<b.r);} void in(int x) { int s=a[x]; if((++b[s])==1) for(int x=s;x<=n;x+=x&-x) t2[x]++,t1[x]++; else for(int x=s;x<=n;x+=x&-x) t1[x]++; } void ou(int x) { int s=a[x]; if((--b[s])==0) for(int x=s;x<=n;x+=x&-x) t2[x]--,t1[x]--; else for(int x=s;x<=n;x+=x&-x) t1[x]--; } int an1[1000005],an2[1000005]; int main() { //freopen(".in","r",stdin); //freopen(".out","w",stdout); n=read(),m=read();L=sqrt(n); for(int i=1;i<=n;i++) a[i]=read(); for(int i=1;i<=m;i++) q[i]=(que){read(),read(),read(),read(),i}; sort(&q[1],&q[m+1],cmp); int l=1,r=0; for(int i=1;i<=m;i++) {for(;l<q[i].l;ou(l++)); for(;l>q[i].l;in(--l)); for(;r<q[i].r;in(++r)); for(;r>q[i].r;ou(r--)); int H=q[i].h; for(int x=q[i].b;x;x-=x&-x) an1[H]+=t1[x], an2[H]+=t2[x]; for(int x=q[i].a-1;x;x-=x&-x) an1[H]-=t1[x], an2[H]-=t2[x]; } for(int i=1;i<=m;i++) printf("%d %d\n",an1[i],an2[i]); //fclose(stdin); //fclose(stdout); return 0; }
相关文章推荐
- 自定义的IntentFileter 无法找到activity
- Java中的拦截器、过滤器、监听器
- java 厨师,顾客,订餐的多线程示例程序
- iOS之04-方法的声明和实现
- htop的使用
- JAVA数据结构---顺序表
- JAVA数据结构---顺序表
- JAVA数据结构---顺序表
- JAVA数据结构---顺序表
- JAVA数据结构---顺序表
- JAVA数据结构---顺序表
- JAVA数据结构---顺序表
- JAVA数据结构---顺序表
- MFC对话框-UpdateData()函数使用
- Game
- java在内存中的类图学习笔记
- Android不常见系统控件一览
- LatentSVM 算法
- centos7没有安装ifconfig命令的解决方法
- 定时器