zoukankan      html  css  js  c++  java
  • NOI2015

    D1T1

    并查集。

    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<fstream>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<utility>
    #include<set>
    #include<bitset>
    #include<vector>
    #include<functional>
    #include<deque>
    #include<cctype>
    #include<climits>
    #include<complex>
    //#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj
     
    using namespace std;
    
    typedef long long LL;
    typedef double DB;
    typedef pair<int,int> PII;
    typedef complex<DB> CP;
    
    #define mmst(a,v) memset(a,v,sizeof(a))
    #define mmcy(a,b) memcpy(a,b,sizeof(a))
    #define re(i,a,b)  for(i=a;i<=b;i++)
    #define red(i,a,b) for(i=a;i>=b;i--)
    #define fi first
    #define se second
    #define m_p(a,b) make_pair(a,b)
    #define SF scanf
    #define PF printf
    #define two(k) (1<<(k))
    
    template<class T>inline T sqr(T x){return x*x;}
    template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;}
    template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;}
    
    const DB EPS=1e-9;
    inline int sgn(DB x){if(abs(x)<EPS)return 0;return(x>0)?1:-1;}
    const DB Pi=acos(-1.0);
    
    inline int gint()
      {
            int res=0;bool neg=0;char z;
            for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
            if(z==EOF)return 0;
            if(z=='-'){neg=1;z=getchar();}
            for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
            return (neg)?-res:res; 
        }
    inline LL gll()
      {
          LL res=0;bool neg=0;char z;
            for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
            if(z==EOF)return 0;
            if(z=='-'){neg=1;z=getchar();}
            for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
            return (neg)?-res:res; 
        }
    
    const int maxN=100000;
    const int maxcnt=2*maxN;
    
    int N;
    struct Ta{int e,x,y;}a[maxN+100];
    int cnt,bak[maxcnt+100];
    
    int pa[maxcnt+100];
    inline int findroot(int a){return pa[a]<0?a:pa[a]=findroot(pa[a]);}
    inline void BCJ_Union(int a,int b)
      {
          int f1=findroot(a),f2=findroot(b);
          if(f1==f2)return;
          if(pa[f1]>pa[f2])swap(f1,f2);
          pa[f1]=pa[f1]+pa[f2];
          pa[f2]=f1;
      }
    
    int main()
      {
          freopen("prog.in","r",stdin);
          freopen("prog.out","w",stdout);
          int i;
          for(int Case=gint();Case;Case--)
            {
                N=gint();
                re(i,1,N){a[i].x=gint();a[i].y=gint();a[i].e=gint();}
                cnt=0;
                re(i,1,N){bak[++cnt]=a[i].x;bak[++cnt]=a[i].y;}
                sort(bak+1,bak+cnt+1);
                cnt=unique(bak+1,bak+cnt+1)-bak-1;
                re(i,1,N){a[i].x=lower_bound(bak+1,bak+cnt+1,a[i].x)-bak;a[i].y=lower_bound(bak+1,bak+cnt+1,a[i].y)-bak;}
                re(i,1,cnt)pa[i]=-1;
                re(i,1,N)if(a[i].e==1)BCJ_Union(a[i].x,a[i].y);
                int flag=1;
                re(i,1,N)if(a[i].e==0 && findroot(a[i].x)==findroot(a[i].y)){flag=0;break;}
                if(flag)PF("YES
    ");else PF("NO
    ");
            }
          return 0;
      }
    View Code

    D1T2

    树链剖分+线段树。

    树链剖分中,我们在求边的编号的时候,我们可以用DFS,虽然这样麻烦一点,但是可以保证同一棵子树的编号在线段树中是连续的。

    但考试的时候并没有想到这一点。

    然后用了LCT,打了8KB,我都不想说话了。

    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<fstream>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<utility>
    #include<set>
    #include<bitset>
    #include<vector>
    #include<functional>
    #include<deque>
    #include<cctype>
    #include<climits>
    #include<complex>
    //#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj
     
    using namespace std;
    
    typedef long long LL;
    typedef double DB;
    typedef pair<int,int> PII;
    typedef complex<DB> CP;
    
    #define mmst(a,v) memset(a,v,sizeof(a))
    #define mmcy(a,b) memcpy(a,b,sizeof(a))
    #define re(i,a,b)  for(i=a;i<=b;i++)
    #define red(i,a,b) for(i=a;i>=b;i--)
    #define fi first
    #define se second
    #define m_p(a,b) make_pair(a,b)
    #define SF scanf
    #define PF printf
    #define two(k) (1<<(k))
    
    template<class T>inline T sqr(T x){return x*x;}
    template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;}
    template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;}
    
    const DB EPS=1e-9;
    inline int sgn(DB x){if(abs(x)<EPS)return 0;return(x>0)?1:-1;}
    const DB Pi=acos(-1.0);
    
    inline int gint()
      {
            int res=0;bool neg=0;char z;
            for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
            if(z==EOF)return 0;
            if(z=='-'){neg=1;z=getchar();}
            for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
            return (neg)?-res:res; 
        }
    inline LL gll()
      {
          LL res=0;bool neg=0;char z;
            for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
            if(z==EOF)return 0;
            if(z=='-'){neg=1;z=getchar();}
            for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
            return (neg)?-res:res; 
        }
    
    const int maxN=100000;
    const int maxQ=100000;
    
    struct Tnode
      {
          Tnode *fa,*son[2],*path_parent;
          int R,L,val,add;
          inline Tnode(){fa=son[0]=son[1]=path_parent=0;R=L=val=add=0;}
          inline void down()
            {
                if(add!=0)
                  {
                      if(son[0]){son[0]->val+=add;son[0]->add+=add;}
                      if(son[1]){son[1]->val+=add;son[1]->add+=add;}
                      add=0;
                  }
            }
      };
    
    int N,Q;
    int fa[maxN+100];
    int now,first[maxN+100];
    struct Tedge{int v,next;}edge[maxN+100];
    int dep[maxN+100];
    int jump[maxN+100][31];
    Tnode *pos[maxN+100];
    
    inline void addedge(int u,int v)
      {
          now++;
          edge[now].v=v;
          edge[now].next=first[u];
          first[u]=now;
      }
    
    int head,tail,que[maxN+100];
    int size[maxN+100],heavy[maxN+100],top[maxN+100],w[maxN+100],cnt;
    inline void BFS()
      {
          int i,j,u,v;
          dep[que[head=tail=1]=1]=1;
          while(head<=tail)
            {
                u=que[head++];
                for(i=first[u],v=edge[i].v;i!=-1;i=edge[i].next,v=edge[i].v)dep[que[++tail]=v]=dep[u]+1;
            }
          re(i,1,tail)
            {
                u=que[i];
                jump[u][0]=fa[u];
                re(j,1,30)jump[u][j]=jump[jump[u][j-1]][j-1];
            }
          red(j,tail,1)
            {
                u=que[j];
                size[u]=1;
                heavy[u]=-1;
                for(i=first[u],v=edge[i].v;i!=-1;i=edge[i].next,v=edge[i].v)
                  {
                      size[u]+=size[v];
                      if(heavy[u]==-1 || size[v]>size[heavy[u]])heavy[u]=v;
                  }
            }
          top[1]=1;
          re(i,2,tail)
            {
                  u=que[i];
                if(heavy[fa[u]]==u) top[u]=top[fa[u]]; else top[u]=u;
            }
          mmst(w,-1);
          cnt=0;
          re(i,1,tail)
            {
                u=que[i];
                if(w[u]!=-1)continue;
                int r=u;
                while(r!=-1){w[r]=++cnt;r=heavy[r];}
            }
      };
    
    int tree[4*maxN+100];
    inline void down(int root)
      {
          if(tree[root]!=0)
            {
                tree[root*2]=tree[root*2+1]=tree[root];
                tree[root]=0;
            }
      }
    inline void update(int root,int l,int r,int x,int y,int val)
      {
          if(l>r || x>y || r<x || y<l) return;
          if(x<=l && r<=y){tree[root]=val;return;}
          down(root);
          int mid=(l+r)/2;
          update(root*2,l,mid,x,y,val);
          update(root*2+1,mid+1,r,x,y,val);
      }
    inline int ask(int root,int l,int r,int x)
      {
          if(l<=x && x<=r && tree[root]!=0) return tree[root];
          if(x<=l && r<=x) return tree[root];
          down(root);
          int mid=(l+r)/2;
          if(x<=mid) return ask(root*2,l,mid,x); else return ask(root*2+1,mid+1,r,x);
      }
    inline void Cover(int a,int b,int val)
      {
          int f1=top[a],f2=top[b];
          while(f1!=f2)
            {
                if(dep[f1]<dep[f2]){swap(f1,f2);swap(a,b);}
                update(1,1,cnt,w[f1],w[a],val);
                a=fa[f1];
                f1=top[a];
            }
          if(dep[a]>dep[b])swap(a,b);
          update(1,1,cnt,w[a],w[b],val);
      }
    inline Tnode *findp(int x)
      {
          if(x==0) return pos[0];
          x=ask(1,1,cnt,w[x]);
          return (x==0)?0:pos[x];
      }
    
    inline void Splay_Rotate(Tnode *x,int flag)
      {
          Tnode *y=x->fa,*z=y->fa;
          y->son[flag^1]=x->son[flag];if(x->son[flag])x->son[flag]->fa=y;
          x->son[flag]=y;y->fa=x;
          x->path_parent=y->path_parent;y->path_parent=0;
          x->fa=z;if(z)z->son[(y==z->son[1])]=x;
      }
    inline void Splay(Tnode *x)
      {
          Tnode *y,*z;
          while(x->fa)
            {
                y=x->fa;z=y->fa;
                if(z)z->down();y->down();x->down();
                if(!z){Splay_Rotate(x,x==y->son[0]);return;}
                int L=(x==y->son[0]),R=(y==z->son[0]);
                if(L==R){Splay_Rotate(y,L);Splay_Rotate(x,R);continue;}
                if(L!=R){Splay_Rotate(x,L);Splay_Rotate(x,R);continue;}
            }
          x->down();
      }
    inline void LCT_Access(Tnode *x)
      {
          Tnode *y;
          for(y=0;x;y=x,x=x->path_parent)
            {
                Splay(x);
                if(x->son[1]){x->son[1]->fa=0;x->son[1]->path_parent=x;}
                x->son[1]=y;
                if(y){y->fa=x;y->path_parent=0;}
            }
      }
    inline void LCT_update(Tnode *x,int v)
      {
          LCT_Access(x);
          Splay(x);
          x->val+=v;
          x->add+=v;
          x->down();
      }
    inline void LCT_Delete(Tnode *u,Tnode *v)
      {
          LCT_Access(u);
          LCT_Access(v);
          u->path_parent=0;
      }
    inline int swim(int x,int H)
      {
          int res=x;
          for(int i=0;H!=0;H/=2,i++)if(H&1)res=jump[res][i];
          return res;
      }
    inline void LCT_Fen(Tnode *x,int ca)
      {
          int R,L,G;
          Tnode *p;
          if(ca==x->R)return;
          R=x->R;
          L=x->L;
          G=swim(R,dep[R]-dep[ca]-1);
          p=findp(fa[L]);
          LCT_Delete(x,p);
          pos[ca]=new Tnode;
          pos[ca]->path_parent=p;
          pos[ca]->R=ca;
            pos[ca]->L=L;
          pos[ca]->val=x->val;
          Cover(ca,L,ca);
          x->path_parent=pos[ca];
          x->L=G;
          x->val-=dep[ca]-dep[L]+1;
      }
    
    inline int isblack(int x)
      {
          Tnode *p=findp(x);
          if(!p)return 0;
          LCT_Access(p);
          Splay(p);
          Tnode *t=p;t->down();
          while(t->son[0]){t=t->son[0];t->down();}
          return t==pos[0];
      }
    
    inline int findL(int x)
      {
          int i;
          red(i,30,0)if(jump[x][i]!=0 && !isblack(jump[x][i])) x=jump[x][i];
          return x;
      }
    
    int main()
      {
          freopen("manager.in","r",stdin);
          freopen("manager.out","w",stdout);
          int i;
          N=gint();
          now=-1;mmst(first,-1);
          re(i,2,N)
              {
                  fa[i]=gint()+1;
                  addedge(fa[i],i);
                }
          BFS();
          pos[0]=new Tnode;
          Q=gint();
          while(Q--)
            {
                char s[20];int x,ca,R,L;
                Tnode *p;
                SF("%s%d
    ",s,&x);x++;
                switch(s[0])
                  {
                      case 'i':
                          if(isblack(x)){PF("0
    ");continue;}
                          L=findL(x);
                          ca=fa[L];
                          p=findp(ca);
                          LCT_Fen(p,ca);
                          pos[x]=new Tnode;
                          pos[x]->R=x;pos[x]->L=L;
                          Cover(x,L,x);
                          pos[x]->path_parent=findp(ca);
                          LCT_update(pos[x],dep[x]-dep[ca]);
                          PF("%d
    ",dep[x]-dep[ca]);
                      break;
                      case 'u':
                          if(!isblack(x)){PF("0
    ");continue;}
                          p=findp(x);
                          R=p->R;
                                L=p->L;
                                ca=fa[L];
                          PF("%d
    ",p->val-(dep[x]-dep[L]));
                          LCT_update(p,-p->val);
                                LCT_Delete(p,findp(ca));
                                //////////
                                if(x==L)continue;
                                x=fa[x];
                                pos[x]=new Tnode;
                          pos[x]->R=x;pos[x]->L=L;
                          Cover(x,L,x);
                          pos[x]->path_parent=findp(ca);
                          LCT_update(pos[x],dep[x]-dep[ca]);
                      break;
                  }
            }
          return 0;
      }
    View Code

    D1T3

    背包+状压DP。

    神题。。。。。。

    ppt讲得比较清晰了。

    30%的做法:

    集合A和集合B互质就是没有包含相同的质因数,我们将每个数分解质因数。

    分解质因数求出每个数包含哪些质因子,使用二进制状态压缩,存在s[i]里,每个数看作一个物品,做一次二进制状态的背包DP。

    容易得到g[j|s[i]]=(g[j|s[i]]+g[j])%Mod

    这是一个背包,所以j倒序循环。

    100%的做法:

    注意到小于等于sqrt(N)的质因数最多只有9个,每一个数最多包含一个大于sqrt(N)的质因数。

    s[i]就表示i在2...sqrt(N)中包含哪些质因子,使用二进制状态压缩。

    f(i)[x][y]表示可以使用前i个大质数和全部小质数,A集合包含的小质数的状态为x(二进制),B集合包含的小质数的状态为y(二进制)时的方案数。

    容易得到初值f(0)[x][y]=g[x]*g[y]%Mod,其中x&y==0。

    其中i这一维可以在背包中忽略。

    转移时,枚举包含第i个大质数的所有整数z,他们可以某些且至少一个分配在A集合,可以某些且至少一个分配在B集合,也可以全部丢弃不用。单是绝对不可以某些分配在A集合,某些分配在B集合。

    我们在做第i个大质数的时候,记d[x][y][0]表示A集合包含的小质数的状态为x(二进制),B集合包含的小质数的状态为y(二进制),包含第i个大质数的所有至少一个整数z都分配在A集合中的方案数。

    同理,d[x][y][0]表示A集合包含的小质数的状态为x(二进制),B集合包含的小质数的状态为y(二进制),包含第i个大质数的某些且至少一个整数z都分配在B集合中的方案数。

    分给A:d[x|s[z]][y][0]=(d[x|s[z]][y][0]+d[x][y][0]+f[x][y])%Mod

    分给B:d[x][y|s[z]][1]=(d[x][y|s[z]][1]+d[x][y][0]+f[x][y])%Mod

    这是一个背包,所以x和y倒序循环。

    至于为什么还要加上一个f[x][y],因为d[x][y][0]是前面用了至少一个整数z,但是有可能前面没有用整数z,用了当前的整数z,所以要加f[x][y]。

    累加:f[x][y]=(f[x][y]+d[x][y][0]+d[x][y][1])%Mod

    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<fstream>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<utility>
    #include<set>
    #include<bitset>
    #include<vector>
    #include<functional>
    #include<deque>
    #include<cctype>
    #include<climits>
    #include<complex>
    //#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj
     
    using namespace std;
    
    typedef long long LL;
    typedef double DB;
    typedef pair<int,int> PII;
    typedef complex<DB> CP;
    
    #define mmst(a,v) memset(a,v,sizeof(a))
    #define mmcy(a,b) memcpy(a,b,sizeof(a))
    #define re(i,a,b)  for(i=a;i<=b;i++)
    #define red(i,a,b) for(i=a;i>=b;i--)
    #define fi first
    #define se second
    #define m_p(a,b) make_pair(a,b)
    #define SF scanf
    #define PF printf
    
    template<class T>inline T sqr(T x){return x*x;}
    template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;}
    template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;}
    
    const DB EPS=1e-9;
    inline int sgn(DB x){if(abs(x)<EPS)return 0;return(x>0)?1:-1;}
    const DB Pi=acos(-1.0);
    
    inline int gint()
      {
            int res=0;bool neg=0;char z;
            for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
            if(z==EOF)return 0;
            if(z=='-'){neg=1;z=getchar();}
            for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
            return (neg)?-res:res; 
        }
    inline LL gll()
      {
          LL res=0;bool neg=0;char z;
            for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
            if(z==EOF)return 0;
            if(z=='-'){neg=1;z=getchar();}
            for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
            return (neg)?-res:res; 
        }
    
    const int maxN=500;
    
    int N;
    LL Mod;
    int flag[maxN+100];
    int cnt,ge,prime[maxN+100];
    int s[maxN+100];
    LL g[(1<<10)+100];
    LL f[(1<<9)+10][(1<<9)+10],d[(1<<9)+10][(1<<9)+10][2];
    LL ans;
    
    #define wei(v,k) (((v)>>((k)-1))&1)
    #define two(k) (1<<(k-1))
    
    int main()
      {
          freopen("dinner.in","r",stdin);
          freopen("dinner.out","w",stdout);
          int i,j,k;
          N=gint();Mod=gll();
          re(i,2,N)
            {
                if(!flag[i])prime[++cnt]=i;
                for(j=1;j<=cnt && prime[j]*i<=N;j++)
                  {
                      flag[i*prime[j]]=1;
                      if(i%prime[j]==0)break;
                  }
            }
          if(cnt<=10)
            {
                  re(i,2,N)re(j,1,cnt)if(i%prime[j]==0)s[i]|=two(j);
                  g[0]=1;
                  re(i,2,N)red(j,(1<<cnt)-1,0)g[j|s[i]]=(g[j|s[i]]+g[j])%Mod;
                  ans=0;
                  re(i,0,(1<<cnt)-1)re(j,0,(1<<cnt)-1)if((i&j)==0)ans=(ans+g[i]*g[j])%Mod;
                  cout<<ans<<endl;
            }
          else
            {
                ge=9;
                re(i,2,N)re(j,1,ge)if(i%prime[j]==0)s[i]|=two(j);
                g[0]=1;
                re(i,2,N)
                  {
                      int t=i;
                      re(j,1,ge)while(t%prime[j]==0)t/=prime[j];
                      if(t!=1)continue;
                      red(j,(1<<ge)-1,0)g[j|s[i]]=(g[j|s[i]]+g[j])%Mod;
                  }
                re(i,0,(1<<ge)-1)re(j,0,(1<<ge)-1)if((i&j)==0)f[i][j]=g[i]*g[j]%Mod;
                re(k,ge+1,cnt)
                  {
                      mmst(d,0);
                    for(int v=prime[k];v<=N;v+=prime[k])
                      red(i,(1<<ge)-1,0)red(j,(1<<ge)-1,0)if((i&j)==0)
                        {
                            if(((i|s[v])&j)==0)d[i|s[v]][j][0]=(d[i|s[v]][j][0]+d[i][j][0]+f[i][j])%Mod;
                            if((i&(j|s[v]))==0)d[i][j|s[v]][1]=(d[i][j|s[v]][1]+d[i][j][1]+f[i][j])%Mod;
                        }
                    re(i,0,(1<<ge)-1)re(j,0,(1<<ge)-1)if((i&j)==0)f[i][j]=(f[i][j]+d[i][j][0]+d[i][j][1])%Mod;
                  }
                ans=0;
                re(i,0,(1<<ge)-1)re(j,0,(1<<ge)-1)if((i&j)==0)ans=(ans+f[i][j])%Mod;
                cout<<ans<<endl;
            }
          return 0;
      }
    View Code

     D2T1

    多叉哈夫曼树。

    如果K=2,那就是裸的哈夫曼树。现在K不是2,就是多叉哈夫曼树。

    根据二叉哈夫曼树的类比,我们可以得到多叉哈夫曼树的做法:将前K小的点拿出来,然后删去,再加入一个权值等于和的点。

    但是有几点地方要注意,有可能最后会剩下小于K个,这样无法取,我们在一开始的时候就补若干个0,使得个数为(K-1)的倍数+1

    对于第二问,我们可以可以再排序的时候设置第二关键字,先取深度小的。

    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<fstream>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<utility>
    #include<set>
    #include<bitset>
    #include<vector>
    #include<functional>
    #include<deque>
    #include<cctype>
    #include<climits>
    #include<complex>
    //#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj
     
    using namespace std;
    
    typedef long long LL;
    typedef double DB;
    typedef pair<LL,LL> PLL;
    typedef complex<DB> CP;
    
    #define mmst(a,v) memset(a,v,sizeof(a))
    #define mmcy(a,b) memcpy(a,b,sizeof(a))
    #define re(i,a,b)  for(i=a;i<=b;i++)
    #define red(i,a,b) for(i=a;i>=b;i--)
    #define fi first
    #define se second
    #define m_p(a,b) make_pair(a,b)
    #define SF scanf
    #define PF printf
    #define two(k) (1<<(k))
    
    template<class T>inline T sqr(T x){return x*x;}
    template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;}
    template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;}
    
    const DB EPS=1e-9;
    inline int sgn(DB x){if(abs(x)<EPS)return 0;return(x>0)?1:-1;}
    const DB Pi=acos(-1.0);
    
    inline int gint()
      {
            int res=0;bool neg=0;char z;
            for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
            if(z==EOF)return 0;
            if(z=='-'){neg=1;z=getchar();}
            for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
            return (neg)?-res:res; 
        }
    inline LL gll()
      {
          LL res=0;bool neg=0;char z;
            for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
            if(z==EOF)return 0;
            if(z=='-'){neg=1;z=getchar();}
            for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
            return (neg)?-res:res; 
        }
    
    int N,K;
    
    struct cmp{inline bool operator ()(PLL x,PLL y){return (x.fi==y.fi)?x.se>y.se:x.fi>y.fi;}};
    priority_queue<PLL,vector<PLL>,cmp>Q;
    LL ans,cnt;
    
    int main()
      {
          freopen("epic.in","r",stdin);
          freopen("epic.out","w",stdout);
          int i;
          N=gint();K=gint();
          re(i,1,N)Q.push(PLL(gll(),1));
          while((N-1)%(K-1)!=0)Q.push(PLL(0,1)),N++;
          while(Q.size()!=1)
            {
                PLL t=PLL(0,0);
                re(i,1,K){t.fi+=Q.top().fi;upmax(t.se,Q.top().se+1);Q.pop();}
                ans+=t.fi;
                Q.push(t);
            }
          cout<<ans<<endl;
          cout<<Q.top().se-1<<endl;
          return 0;
      }
    View Code

    D2T2

    后缀数组+并查集。

    这种问题好像经常遇到,至少看到过2次了,后缀数组一定要熟悉啊。

    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<fstream>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<utility>
    #include<set>
    #include<bitset>
    #include<vector>
    #include<functional>
    #include<deque>
    #include<cctype>
    #include<climits>
    #include<complex>
    //#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj
     
    using namespace std;
    
    typedef long long LL;
    typedef double DB;
    typedef pair<int,int> PII;
    typedef complex<DB> CP;
    
    #define mmst(a,v) memset(a,v,sizeof(a))
    #define mmcy(a,b) memcpy(a,b,sizeof(a))
    #define re(i,a,b)  for(i=a;i<=b;i++)
    #define red(i,a,b) for(i=a;i>=b;i--)
    #define fi first
    #define se second
    #define m_p(a,b) make_pair(a,b)
    #define SF scanf
    #define PF printf
    #define two(k) (1<<(k))
    
    template<class T>inline T sqr(T x){return x*x;}
    template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;}
    template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;}
    
    const DB EPS=1e-9;
    inline int sgn(DB x){if(abs(x)<EPS)return 0;return(x>0)?1:-1;}
    const DB Pi=acos(-1.0);
    
    inline int gint()
      {
            int res=0;bool neg=0;char z;
            for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
            if(z==EOF)return 0;
            if(z=='-'){neg=1;z=getchar();}
            for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
            return (neg)?-res:res; 
        }
    inline LL gll()
      {
          LL res=0;bool neg=0;char z;
            for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
            if(z==EOF)return 0;
            if(z=='-'){neg=1;z=getchar();}
            for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
            return (neg)?-res:res; 
        }
    
    const int maxN=300000;
    const LL INF=1LL<<62;
    
    int N;
    char S[maxN+100];
    LL a[maxN+100];
    
    int r[maxN+100],sa[maxN+100],rank[maxN+100],height[maxN+100];
    int table[maxN+100],wa[maxN+100],wb[maxN+100];
    inline bool cmp(int *r,int a,int b,int len){return r[a]==r[b] && r[a+len]==r[b+len];}
    inline void da()
      {
            int i,j,k,p,*x=wa,*y=wb,tol;
            re(i,1,N)r[i]=S[i]-' '+1;
            p=0;re(i,1,N)upmax(p,x[i]=r[i]);
            re(i,1,p)table[i]=0;
            re(i,1,N)table[x[i]]++;
            re(i,2,p)table[i]+=table[i-1];
            red(i,N,1)sa[table[x[i]]--]=i;
            for(swap(x,y),x[sa[1]]=p=1,i=2;i<=N;i++)
              x[sa[i]]=cmp(y,sa[i-1],sa[i],0)?p:++p;
            for(j=1;p<N;j*=2)
              {
                    tol=0;
                    re(i,N-j+1,N)y[++tol]=i;
                    re(i,1,N)if(sa[i]-j>=1)y[++tol]=sa[i]-j;
                    re(i,1,p)table[i]=0;
                    re(i,1,N)table[x[y[i]]]++;
                    re(i,2,p)table[i]+=table[i-1];
                    red(i,N,1)sa[table[x[y[i]]]--]=y[i];
                    for(swap(x,y),x[sa[1]]=p=1,i=2;i<=N;i++)
                      x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p:++p;
                }
            re(i,1,N)rank[sa[i]]=i;
            for(i=1,j,k=0;i<=N-1;height[rank[i++]]=k)
              for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++);
        }
    
    LL ge,As;
    LL ans1[maxN+100],ans2[maxN+100];
    struct Tbak
      {
          int val,pos;
          inline Tbak(int _val=0,int _pos=0){val=_val;pos=_pos;}
        }bak[maxN+100];int cnt;
    inline bool cmpbak(Tbak a,Tbak b){return a.val>b.val;}
    
    PII route[maxN+100];
    LL o[maxN+100],Q1[maxN+100],Q2[maxN+100],Q3[maxN+100],Q4[maxN+100];
    /*
    Q1 最大非负数
    Q2 最小非负数
    Q3 最大非正数 
    Q4 最小非正数 
    */ 
    int pa[maxN+100];
    inline int findroot(int a){return pa[a]<0?a:pa[a]=findroot(pa[a]);}
    
    int main()
      {
          freopen("savour.in","r",stdin);
          freopen("savour.out","w",stdout);
          int i;
          N=gint();
          scanf("%s
    ",S+1);
          re(i,1,N)a[i]=gll();
          S[++N]=' ';
          da();
          
          re(i,1,N)o[rank[i]]=a[i];
            re(i,1,N)
              {
                  pa[i]=-1;
                    route[i]=PII(i,i);
                    if(o[i]>=0) Q1[i]=o[i]; else Q1[i]=-INF;
                    if(o[i]>=0) Q2[i]=o[i]; else Q2[i]=INF;
                    if(o[i]<=0) Q3[i]=o[i]; else Q3[i]=-INF;
                    if(o[i]<=0) Q4[i]=o[i]; else Q4[i]=INF;
                }
            
          re(i,3,N)bak[++cnt]=Tbak(height[i],i);
          sort(bak+1,bak+cnt+1,cmpbak);
          int head=1;
          ge=0;As=-INF;
          red(i,N-2,0)
            {
                while(head<=cnt && bak[head].val==i)
                  {
                      int f1=findroot(bak[head].pos-1),f2=findroot(bak[head].pos);
                      PII D1=route[f1],D2=route[f2];
                      ge+=LL(D1.se-D1.fi+1)*LL(D2.se-D2.fi+1);
                      if(Q1[f1]!=-INF && Q1[f2]!=-INF) upmax(As,Q1[f1]*Q1[f2]);
                      if(Q4[f1]!=INF && Q4[f2]!=INF) upmax(As,Q4[f1]*Q4[f2]);
                      if(Q2[f1]!=INF && Q3[f2]!=-INF) upmax(As,Q2[f1]*Q3[f2]);
                      if(Q3[f1]!=-INF && Q2[f2]!=INF) upmax(As,Q3[f1]*Q2[f2]);
                      
                      if(pa[f1]>pa[f2])swap(f1,f2);
                      pa[f1]=pa[f1]+pa[f2];
                      pa[f2]=f1;
                      route[f1]=PII(D1.fi,D2.se);
                      upmax(Q1[f1],Q1[f2]);
                      upmin(Q2[f1],Q2[f2]);
                      upmax(Q3[f1],Q3[f2]);
                      upmin(Q4[f1],Q4[f2]);
                      
                      head++;
                  }
                ans1[i]=ge;
                ans2[i]=(ge==0)?0:As;
            }
          re(i,0,N-2)printf("%I64d %I64d
    ",ans1[i],ans2[i]);
          return 0;
      }
    
          
    View Code
  • 相关阅读:
    社会影响力入门:打造有所作为的公司
    JSP中的include有哪些?有什么差别?
    关于程序猿怎样降低程序Bug的若干建议
    linux文件打开模式
    IntelliJ IDEA 问题总结之中的一个 —— jar包、assets、maven、git
    linux下改动内核參数进行Tcp性能调优 -- 高并发
    思科模拟器配置三层交换机局域网
    MFC调试小技巧
    JAVA基础编程50题(10-12题)具体解释
    加速度传感器的原理和应用-手机翻转、失重检测、运动检测、位置识别
  • 原文地址:https://www.cnblogs.com/maijing/p/4678062.html
Copyright © 2011-2022 走看看