zoukankan      html  css  js  c++  java
  • 小Z的袜子(hose) &&作业 (莫队)

    莫队:一种非常优雅的暴力,时间复杂度一般情况下是n*根号n,还是很优秀的。

    今天水了三道莫队题,对普通莫队有了些了解

    1.莫队l和r为指针,维护当前区间的某些信息,一般可以是当前区间不同权值的个数,(或许可以再加些限制)

    2.莫队指针移动时的操作一定是O(1)最多O(log(n)),

    3.当减值时先减当前的再加,加则反。

    T1

    水题,维护当前区间sum[i]*sum[i]的和,在进行操作即可

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<string>
     5 #include<algorithm>
     6 #include<cmath>
     7 #include<stack>
     8 #include<map>
     9 #include<queue>
    10 #define ps push_back
    11 #define MAXN 55101
    12 #define ll long long
    13 using namespace std;
    14 ll kuan;
    15 struct node{ll l,r,id,zi,mu;}e[MAXN];
    16 ll se[MAXN],sum[MAXN];
    17 bool cmp(node a,node b)
    18 {
    19    return ((a.l/kuan)!=(b.l/kuan))?(a.l<b.l):(a.r<b.r);
    20 }
    21 bool CMP(node a,node b)
    22 {
    23    return a.id<b.id;
    24 }
    25 ll n,m;ll ans=0;
    26 void jian(ll x)
    27 {
    28     ans-=sum[se[x]]*sum[se[x]];sum[se[x]]--;ans+=sum[se[x]]*sum[se[x]];
    29 }
    30 void add(ll x)
    31 {
    32     ans-=sum[se[x]]*sum[se[x]];sum[se[x]]++;ans+=sum[se[x]]*sum[se[x]];
    33 }
    34 ll gcd(ll a,ll b)
    35 {
    36     return (b==0)?a:gcd(b,a%b);
    37 }
    38 int main()
    39 {
    40    scanf("%lld%lld",&n,&m);kuan=sqrt(n);
    41    for(ll i=1;i<=n;++i)
    42    {
    43       ll x;
    44       scanf("%lld",&se[i]);
    45    }
    46    for(ll i=1;i<=m;++i)
    47    {
    48       ll l,r;
    49       scanf("%lld%lld",&e[i].l,&e[i].r);
    50       e[i].id=i;
    51    }
    52    sort(e+1,e+m+1,cmp);
    53    ll l=1,r=0;
    54    for(ll i=1;i<=m;++i)
    55    {
    56        //printf("l=%lld e[i].l=%lld r=%lld e[i].r=%lld
    ",l,e[i].l,r,e[i].r);
    57        while(l<e[i].l){jian(l++);}
    58        while(l>e[i].l){add(--l);}
    59        while(r<e[i].r){add(++r);}
    60        while(r>e[i].r){jian(r--);}
    61        e[i].zi=ans-(e[i].r-e[i].l+1);
    62        e[i].mu=(e[i].r-e[i].l+1)*(e[i].r-e[i].l);
    63        if(e[i].zi==0){e[i].mu=1;continue;}
    64        ll gcdd=gcd(e[i].zi,e[i].mu);
    65        e[i].zi/=gcdd;e[i].mu/=gcdd;
    66        //printf("%lld %lld
    ",e[i].zi,e[i].mu);
    67    }
    68    sort(e+1,e+m+1,CMP);
    69    for(ll i=1;i<=m;++i)
    70    {
    71        printf("%lld/%lld
    ",e[i].zi,e[i].mu);
    72    }
    73    
    74 }
    View Code

    T2

    树状数组一个维护当前区间中<=某个数的个数

    一个维护<=某个数出现的不同权值的个数

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<string>
      5 #include<algorithm>
      6 #include<cmath>
      7 #include<stack>
      8 #include<map>
      9 #include<queue>
     10 #define ps push_back
     11 #define MAXN 205101
     12 #define ll long long
     13 using namespace std;
     14 struct node{int l,r,id,A,B,ans1,ans2;}e[10*MAXN];
     15 int kuan;int se[MAXN],c[MAXN];
     16 bool cmp(node a,node b){return (a.l/kuan!=b.l/kuan)?(a.l<b.l):(a.r<b.r);}
     17 bool CMP(node a,node b){return a.id<b.id;}
     18 int lowbit(int x){return x&(-x);}int n,m;
     19 void shu_add(int x,int k)
     20 {
     21    for(int i=x;i<=n;i+=lowbit(i))
     22    {
     23         c[i]+=k;
     24    }
     25 }
     26 int get_sum(int x)
     27 {
     28    int ans=0;
     29    for(int i=x;i>=1;i-=lowbit(i))
     30    {
     31         ans+=c[i];
     32    }
     33    return ans;
     34 }
     35 int d[MAXN];int sum[MAXN];
     36 void shu_cishu(int x,int k)
     37 {
     38    for(int i=x;i<=n;i+=lowbit(i))
     39    {
     40        d[i]+=k;
     41    }
     42 }
     43 int get_sum_cishu(int x)
     44 {
     45    int ans=0;
     46    for(int i=x;i>=1;i-=lowbit(i))
     47    {
     48        ans+=d[i];
     49    }
     50    return ans;
     51 }
     52 void add(int x)
     53 {
     54    if(sum[se[x]]==0)
     55    {
     56       shu_cishu(se[x],1); 
     57    }
     58    sum[se[x]]++;
     59    shu_add(se[x],1);
     60 }
     61 void jian(int x)
     62 {
     63    sum[se[x]]--; 
     64    if(sum[se[x]]==0)
     65    {
     66       shu_cishu(se[x],-1);
     67    }
     68    shu_add(se[x],-1);
     69 }
     70 int main()
     71 {
     72    scanf("%d%d",&n,&m);
     73    kuan=sqrt(n);
     74    for(int i=1;i<=n;++i)
     75    {
     76        scanf("%d",&se[i]);
     77    }
     78    for(int i=1;i<=m;++i)
     79    {
     80        scanf("%d%d%d%d",&e[i].l,&e[i].r,&e[i].A,&e[i].B);
     81        if(e[i].r>n)e[i].r=n;
     82        if(e[i].A>n)e[i].A=n;
     83        if(e[i].B>n)e[i].B=n;
     84        e[i].id=i;
     85    }
     86    sort(e+1,e+m+1,cmp);
     87    int l=1,r=0;
     88    for(int i=1;i<=m;++i)
     89    {
     90       while(l<e[i].l){jian(l++);}
     91       while(l>e[i].l){add(--l);}
     92       while(r<e[i].r){add(++r);}
     93       while(r>e[i].r){jian(r--);}
     94       int A=e[i].A,B=e[i].B;
     95       e[i].ans1=get_sum(B)-((A-1!=0)?get_sum(A-1):0);
     96       e[i].ans2=get_sum_cishu(B)-((A-1!=0)?get_sum_cishu(A-1):0);
     97    }
     98    sort(e+1,e+m+1,CMP);
     99    for(int i=1;i<=m;++i)
    100    {
    101       printf("%d %d
    ",e[i].ans1,e[i].ans2);
    102    }
    103 }
    View Code
  • 相关阅读:
    差分约束
    c++ 添加
    2 jQuery的入口函数
    1 jQuery的概述
    清除浮动的常用4种方式
    虚函数指针和它对应的虚函数表
    对于C++中顿悟
    前端和后端交互的一些认识
    前端初学者一看就懂:Ajax调用后台接口案例(转)
    前端和后端是怎么交互的(转)
  • 原文地址:https://www.cnblogs.com/Wwb123/p/11240954.html
Copyright © 2011-2022 走看看