zoukankan      html  css  js  c++  java
  • P2709 小B的询问(莫队入门)

    题目链接:https://www.luogu.org/problemnew/show/P2709

    题目大意:中文题目

    具体思路:莫队入门题,按照离线的方式打的,对每一个区间进行分块和编号,如果在同一个块里面就按照右端点从小到大排列,如果不在同一个块里面就按照块的下标开始排序,这里的块是按照数列分块里面的方法来进行的,查询每个区间的值就可以了。

    对于l,r指针的移动,当l<q[i].l的时候,我们需要将l指针往右移动,所以假设t为当前的颜色,ans为未移动的时候的值,首先去除掉原来的值的影响,ans-=t*t,然后再加上新的值的影响,ans+=(t+1)*(t+1),因为我们是先进行加减操作,所以这种情况下ans=-(t-1)*(t-1)+t*t=2*t-1.其他情况同理。

    AC代码:

     1 #include<iostream>
     2 #include<stack>
     3 #include<cstring>
     4 #include<iomanip>
     5 #include<stdio.h>
     6 #include<cmath>
     7 #include<algorithm>
     8 #include<vector>
     9 using namespace std;
    10 # define ll long long
    11 const int maxn = 2e5+100;
    12 int a[maxn];
    13 struct node{
    14 int l,r,pos,id;
    15 bool friend operator < (node t1,node t2){
    16 if(t1.pos==t2.pos)return t1.r<t2.r;
    17 return t1.pos<t2.pos;
    18 }
    19 }q[maxn];
    20 int ans[maxn],vis[maxn];
    21 int main(){
    22 int n,m,k;
    23 scanf("%d %d %d",&n,&m,&k);
    24 int block=(int)sqrt(n);
    25 for(int i=1;i<=n;i++){
    26 scanf("%d",&a[i]);
    27 }
    28 for(int i=1;i<=m;i++){
    29 scanf("%d %d",&q[i].l,&q[i].r);
    30 q[i].pos=(q[i].l-1)/block+1;
    31 q[i].id=i;
    32 }
    33 sort(q+1,q+m+1);
    34 int tmp=0;
    35 int l=1,r=0;
    36 for(int i=1;i<=m;i++){
    37 while(l<q[i].l)vis[a[l]]--,tmp-=(2*vis[a[l]]+1),l++;
    38 while(l>q[i].l)l--,vis[a[l]]++,tmp+=2*vis[a[l]]-1;
    39 while(r<q[i].r)r++,vis[a[r]]++,tmp+=2*vis[a[r]]-1;
    40 while(r>q[i].r)vis[a[r]]--,tmp-=2*vis[a[r]]+1,r--;
    41 ans[q[i].id]=tmp;
    42 }
    43 for(int i=1;i<=m;i++){
    44 printf("%d
    ",ans[i]);
    45 }
    46 return 0;
    47 }
  • 相关阅读:
    【二分图匹配入门专题1】L
    【二分图匹配入门专题1】K
    【km算法模板+总结】
    【二分匹配入门专题1】J
    【自定义博客园~~~】
    【二分图匹配入门专题1】I
    【二分图匹配入门专题1】H
    【二分图匹配入门专题1】G
    【二分图匹配入门专题1】E
    【二分图匹配入门专题1】F
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10487444.html
Copyright © 2011-2022 走看看