3236: [Ahoi2013]作业
Time Limit: 100 Sec Memory Limit: 512 MB
Submit: 1744 Solved: 702
[Submit][Status][Discuss]
Description
Input
Output
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
Source
思路:莫队套权值树状数组。
错因:数组开小了。
莫队套树状数组:
#include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define MAXN 1000001 using namespace std; int n,m,S,ans; int num[MAXN],sum[MAXN],c[2][MAXN]; struct nond{ int l,r,a,b; int id,pos,ans,sum; }edge[MAXN]; int cmp(nond a,nond b){ if(a.pos==b.pos) return a.r<b.r; else return a.pos<b.pos; } int cmp1(nond a,nond b){ return a.id<b.id; } int lowbit(int x){ return x&(-x); } void change(int k,int w,int h){ while(k<=n){ c[h][k]+=w; k+=lowbit(k); } } int query(int k,int h){ int tot=0; while(k){ tot+=c[h][k]; k-=lowbit(k); } return tot; } void up(int x,int k){ sum[num[x]]+=k; change(num[x],k,1); if(k==1&&sum[num[x]]==1) change(num[x],k,0); else if(k==-1&&sum[num[x]]==0) change(num[x],k,0); } void mode(){ int l=1,r=0; for(int i=1;i<=m;i++){ while(l<edge[i].l) up(l++,-1); while(l>edge[i].l) up(--l,1); while(r<edge[i].r) up(++r,1); while(r>edge[i].r) up(r--,-1); edge[i].sum=query(edge[i].b,0)-query(edge[i].a-1,0); edge[i].ans=query(edge[i].b,1)-query(edge[i].a-1,1); } } int main(){ freopen("ahoi2013_homework.in","r",stdin); freopen("ahoi2013_homework.out","w",stdout); scanf("%d%d",&n,&m); S=sqrt(n); for(int i=1;i<=n;i++) scanf("%d",&num[i]); for(int i=1;i<=m;i++){ scanf("%d%d%d%d",&edge[i].l,&edge[i].r,&edge[i].a,&edge[i].b); edge[i].id=i; edge[i].pos=(edge[i].l-1)/S+1; } sort(edge+1,edge+1+m,cmp); mode(); sort(edge+1,edge+1+m,cmp1); for(int i=1;i<=m;i++) cout<<edge[i].ans<<" "<<edge[i].sum<<endl; }
莫队套线段树:
时间: 2024-10-20 21:01:44