zoukankan      html  css  js  c++  java
  • 莫队算法

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    
      long long  lm,rm;
      long long c[50001],a[50001];
      long long t1,t2;
      long long ans;
      
      struct data{
          long long  l,r,key1,num;
      }q[50001];
      
      struct str{
          long long s,m;
      }an[50001];
    
      bool comp(const data &a, const data &b){
          if (a.key1<b.key1) return(1);
          if (a.key1>b.key1) return(0);
          if (a.r<b.r) return(1);
          return(0);
      }
      
      long long gcd(long long a,long long b){
          if (a%b==0) return(b);else return(gcd(b,a%b));
      }
      
      void movel(long long targ){
          if (lm<targ)
            for (;lm<targ;){
              ans=ans-c[a[lm]]*(c[a[lm]]-1)+(c[a[lm]]-1)*(c[a[lm]]-2);
              c[a[lm]]--;
              lm++;
              }
            
        if (lm>targ)
          for (;lm>targ;){
              lm--;
              ans=ans-c[a[lm]]*(c[a[lm]]-1)+c[a[lm]]*(c[a[lm]]+1);
              c[a[lm]]++;
          }  
      }
      
      void mover(long long  targ){
          if (rm<targ)
          for (;rm<targ;){
              rm++;
              ans=ans-c[a[rm]]*(c[a[rm]]-1)+(c[a[rm]]+1)*c[a[rm]];
              c[a[rm]]++;
          }
          
        if (rm>targ)
        for (;rm>targ;){
            ans=ans-c[a[rm]]*(c[a[rm]]-1)+(c[a[rm]]-1)*(c[a[rm]]-2);
            c[a[rm]]--;
            rm--;
        }  
      }
      
      int main(){
           
        long long n,m;
        scanf("%lld%lld",&n,&m);
        int siz=int(sqrt(n));
        
        for (long long i=1;i<=n;i++) scanf("%lld",&a[i]);
        for (long long i=1;i<=m;i++) {
            scanf("%lld%lld",&q[i].l,&q[i].r);
            q[i].key1=q[i].l/siz;
            q[i].num=i;
        }      
        
        sort(q+1,q+m+1,comp);
        
        lm=1,rm=0;
        ans=0;    
         for (long long i=1;i<=m;i++){
            movel(q[i].l);mover(q[i].r);
            t1=ans;t2=(rm-lm+1)*(rm-lm);
            if (t1!=0){
            long long gc=gcd(t1,t2);
            an[q[i].num].s=t1/gc;an[q[i].num].m=t2/gc;
            } else {
                an[q[i].num].s=0;an[q[i].num].m=1;
            }
        }
        
        for (int i=1;i<=m;i++) printf("%lld/%lld
    ",an[i].s,an[i].m);
      }

    BZOJ2038 小Z的袜子

    _________________________________________________________

    带修改莫队与树上莫队

    Codechef FEB17 DISTNUM3

    #include <bits/stdc++.h>
    using namespace std;
      
      int brac[500001][2],lis[500001],cnt,nd[500001],nxt[1000001],des[1000001];
      int dep[500001],fa[500001][21],n,Q,ta[500001],a[500001],opt[500001][3];
      int pre[500001],app[500001],ans,PO,L,R,inq[500001],blo,quecnt,fin[500001];
      int scnt,getnxt[500001],getpre[500001];
      
      struct data{
          int num,orityp,ori;
      }tmp[500001];
      
      int mycomp(const data&a,const data&b){
          return(a.num<b.num);
      }
      
      struct ques{
          int pos,l,r,ori;
      }que[500001];
      
      int mycomp2(const ques&a,const ques&b){
          if (a.pos/blo<b.pos/blo) return(1);
          if (a.pos/blo>b.pos/blo) return(0);
        if (a.l/blo<b.l/blo) return(1);
          if (a.l/blo>b.l/blo) return(0);
          return(a.r<b.r);
      }
      
      void addedge(int x,int y){
          nxt[++scnt]=nd[x];des[scnt]=y;nd[x]=scnt;
      }
      
      void dfs(int po,int f=-1){
          brac[po][0]=++cnt;
          lis[cnt]=po;
          for(int p=nd[po];p!=-1;p=nxt[p])
            if (des[p]!=f){
                dep[des[p]]=dep[po]+1;
                fa[des[p]][0]=po;
                dfs(des[p],po);
          }
        brac[po][1]=++cnt;
        lis[cnt]=po;
      }
      
      void initlca(){
          for (int i=1;i<=20;i++)
            for (int j=1;j<=n;j++)
              fa[j][i]=fa[fa[j][i-1]][i-1];
      }
      
      void initpre(){
          memcpy(ta,a,sizeof(a));
          for (int i=1;i<=Q;i++)
            if (opt[i][0]==2){
              pre[i]=ta[opt[i][1]];
              ta[opt[i][1]]=opt[i][2];
          }
      }
       
      void edi(int po,int num){
          app[po]+=num;
          if (app[po]==1&&num==1) ans++;
          if (app[po]==0&&num==-1) ans--;
      } 
       
      void moverPO(){
        PO=getnxt[PO];
        if (opt[PO][0]==2){
          edi(a[opt[PO][1]],(-1)*inq[opt[PO][1]]);
          a[opt[PO][1]]=opt[PO][2];
          edi(a[opt[PO][1]],1*inq[opt[PO][1]]);
        }
      } 
       
      void movelPO(){
          if (opt[PO][0]==2){
          edi(a[opt[PO][1]],(-1)*inq[opt[PO][1]]);
          a[opt[PO][1]]=pre[PO];
          edi(a[opt[PO][1]],1*inq[opt[PO][1]]);            
        }
        PO=getpre[PO];
      } 
      
      void moverR(){
          R++;
          inq[lis[R]]^=1;
          edi(a[lis[R]],(inq[lis[R]] ? 1:-1));
      }
      
      void movelR(){
          inq[lis[R]]^=1;
          edi(a[lis[R]],(inq[lis[R]] ? 1:-1));
          R--;
      }
      
      void moverL(){
          inq[lis[L]]^=1;
          edi(a[lis[L]],(inq[lis[L]] ? 1:-1));
          L++;
      }
      
      void movelL(){
          L--;
          inq[lis[L]]^=1;
          edi(a[lis[L]],(inq[lis[L]] ? 1:-1));
      }
       
      int getlca(int x,int y){
          if (dep[x]<dep[y]) swap(x,y);
        for (int i=20;i>=0;i--)
          if (dep[fa[x][i]]>=dep[y]) 
            x=fa[x][i];
        for (int i=20;i>=0;i--)
          if (fa[x][i]!=fa[y][i])
            x=fa[x][i],y=fa[y][i];
        if (x==y) return(x);else return(fa[x][0]);
      }  
       
      void initlink(){
          int lst=0;
          for (int i=1;i<=Q;i++)
            if (opt[i][0]==2){
              getpre[i]=lst;
              lst=i;
          }
        getpre[Q+1]=lst;
        lst=Q+1;
        for (int i=Q;i>=1;i--)
          if (opt[i][0]==2){
              getnxt[i]=lst;
              lst=i;
          }
        getnxt[0]=lst;
      } 
       
      int main(){      
          scanf("%d%d",&n,&Q);
          for (int i=1;i<=n;i++) nd[i]=-1;
          for (int i=1;i<=n;i++){
            cnt++;
          tmp[cnt].orityp=1;tmp[cnt].ori=i;
          scanf("%d",&tmp[cnt].num);    
        }
          for (int i=1;i<n;i++){
            int t1,t2;
            scanf("%d%d",&t1,&t2);
          addedge(t1,t2);addedge(t2,t1);    
        }
          for (int i=1;i<=Q;i++){
            scanf("%d%d%d",&opt[i][0],&opt[i][1],&opt[i][2]);
            if (opt[i][0]==2){
              cnt++;
            tmp[cnt].orityp=2;tmp[cnt].ori=i;
            tmp[cnt].num=opt[i][2];    
          }
        }
          
          sort(tmp+1,tmp+cnt+1,mycomp);
          int p=0;tmp[0].num=-1e9;
          for (int i=1;i<=cnt;i++){
            if (tmp[i].num!=tmp[i-1].num) p++;
            if (tmp[i].orityp==1) a[tmp[i].ori]=p;else
              opt[tmp[i].ori][2]=p;
        }
        
        cnt=0;dep[1]=1;
        dfs(1);
        initlca();initpre();
        initlink();
        
        blo=pow(4*n,2.0/3);
        for (int i=1;i<=Q;i++)
          if (opt[i][0]==1){
              if (brac[opt[i][1]][0]>brac[opt[i][2]][0])
                swap(opt[i][1],opt[i][2]);
              quecnt++;
              if (brac[opt[i][1]][1]>brac[opt[i][2]][0])
                que[quecnt].l=brac[opt[i][1]][0],
                que[quecnt].r=brac[opt[i][2]][0];else
                que[quecnt].l=brac[opt[i][1]][1],
                que[quecnt].r=brac[opt[i][2]][0];
              que[quecnt].pos=i;
              que[quecnt].ori=i;
          }
        sort(que+1,que+quecnt+1,mycomp2);
        
        L=1;R=0;PO=0;
        for (int i=1;i<=quecnt;i++){
          while (getnxt[PO]<que[i].pos) moverPO();
          while (PO>que[i].pos) movelPO();
          while (R<que[i].r) moverR();
          while (R>que[i].r) movelR();
          while (L<que[i].l) moverL();
          while (L>que[i].l) movelL();
    
          fin[que[i].ori]=ans;
          int lc=getlca(opt[que[i].ori][1],opt[que[i].ori][2]);
          if ((lc!=opt[que[i].ori][1])&&(lc!=opt[que[i].ori][2]))
            if (!app[a[lc]])
              fin[que[i].ori]++;
        }
        
        for (int i=1;i<=Q;i++)
          if (opt[i][0]==1) 
            printf("%d
    ",fin[i]);
      }
  • 相关阅读:
    5. 图 (算法和数据结构笔记)
    4. 树与二叉树 (算法和数据结构笔记)
    Go第八篇之包的使用
    Go第七篇之规范的接口
    Go第六篇之结构体剖析
    Go第三篇之大话容器
    Go第一篇之轻松入门
    Go第四篇之流程控制
    C简介与环境配置
    程序结构与基本语法
  • 原文地址:https://www.cnblogs.com/zhujiangning/p/5526701.html
Copyright © 2011-2022 走看看