前言
因为两题类似所以一起写了,双倍经验233
Bzoj-1878
看到数据范围,觉得可以莫队啊,但是不会写qwq...
然后发现可以树状数组(By hzwer
然后理解了一下,大概是这样的
把询问按照左右端点排序以后维护的几乎就是一个序列了
"将所有颜色的第一个点x a[x]++
然后从左往右扫
扫到一个点x将a[next[x]]++
碰到一个询问l,r输出sum[r]-sum[l-1]"
听说cxk(Bunny)当初看了10+min就懂了,可怕
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 #define max(a,b) a>b?a:b 5 inline void read(int &x) 6 { 7 x=0;int f=1;char ch=getchar(); 8 while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘) f=-1;ch=getchar();} 9 while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} 10 } 11 int t[50005],n,m,a[50005]; 12 #define l(x) x&-x 13 inline void add(int x,int v){for(;x<=n;x+=l(x))t[x]+=v;} 14 inline int ask(int x){int ans=0;for(;x>0;x-=l(x))ans+=t[x];return ans;} 15 int nxt[50005],mx,p[1000005]; 16 struct pos{int l,r,id,ans;}q[200005]; 17 bool cmp1(pos a,pos b){return a.l==b.l?a.r<b.r:a.l<b.l;} 18 bool cmp2(pos a,pos b){return a.id<b.id;} 19 int main() 20 { 21 read(n);for(int i=1;i<=n;i++){read(a[i]);mx=max(mx,a[i]);} 22 for(int i=n;i;i--){nxt[i]=p[a[i]];p[a[i]]=i;} 23 for(int i=0;i<=mx;i++) if(p[i]) add(p[i],1); 24 read(m);for(int i=1;i<=m;i++){q[i].id=i;read(q[i].l);read(q[i].r);} 25 sort(q,q+m+1,cmp1);int l=1; 26 for(int i=1;i<=m;i++){while(l<q[i].l){if(nxt[l]) add(nxt[l],1);l++;}q[i].ans=ask(q[i].r)-ask(q[i].l-1);} 27 sort(q,q+m+1,cmp2); 28 for(int i=1;i<=m;i++) printf("%d\n",q[i].ans); 29 return 0; 30 }
Bzoj-2743
这道就不能莫队了qwq...反正我还不会写=v=
和上面那道类似,不过这次取nxt[nxt[l]],这样就可以避免取到只有一朵的
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 #define max(a,b) a>b?a:b 5 inline void read(int &x) 6 { 7 x=0;int f=1;char ch=getchar(); 8 while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘) f=-1;ch=getchar();} 9 while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} 10 } 11 int t[1000005],a[1000005],n,m,c; 12 #define l(x) x&-x 13 inline void add(int x,int v){for(;x<=n;x+=l(x))t[x]+=v;} 14 inline int ask(int x){int ans=0;for(;x>0;x-=l(x))ans+=t[x];return ans;} 15 int nxt[1000005],mx,p[1000005]; 16 struct pos{int l,r,id,ans;}q[1000005]; 17 bool cmp1(pos a,pos b){return a.l==b.l?a.r<b.r:a.l<b.l;} 18 bool cmp2(pos a,pos b){return a.id<b.id;} 19 int main() 20 { 21 read(n);read(c);read(m);for(int i=1;i<=n;i++)read(a[i]); 22 for(int i=n;i;i--){nxt[i]=p[a[i]];p[a[i]]=i;} 23 for(int i=1;i<=c;i++) if(nxt[p[i]]) add(nxt[p[i]],1); 24 for(int i=1;i<=m;i++){q[i].id=i;read(q[i].l);read(q[i].r);} 25 sort(q,q+m+1,cmp1);int l=1; 26 for(int i=1;i<=m;i++){while(l<q[i].l){if(nxt[l]) add(nxt[l],-1);if(nxt[nxt[l]]) add(nxt[nxt[l]],1);l++;}q[i].ans=ask(q[i].r)-ask(q[i].l-1);} 27 sort(q,q+m+1,cmp2); 28 for(int i=1;i<=m;i++) printf("%d\n",q[i].ans); 29 return 0; 30 }