• 10.29 考试


    T1

    考试用treap水过了...我自己造的数据明明跑了12s

    (1)Treap

    直接0~m个值全都塞进Treap里,然后就是插入和删除了

    不要用new,要么重载new,要么开数组...

    (2)用队列和单调队列维护

    维护一个cnt表示当前0~cnt卡车上都已经加入过(当前0~cnt的值并不一定在卡车上)

    如果0~cnt都在卡车上,那么ans=cnt+1

    否则,我们需要维护一个红茶编号单调上升的队列记录丢出的红茶

    ans=min(队首,cnt+1)

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <algorithm>
    #include <iostream>
    #include <set>
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    #define rint register int
    #define dd double
    #define ls(x) ((x)->ch[0])
    #define rs(x) ((x)->ch[1])
    #define s(x) ((x)->s)
    #define fix(x) ((x)->fix)
    #define order(x) ((x)->order)
    using namespace std;
    char rea=0;
    inline void read(int &x)
    {
        x=0;
        while(rea<'0'||rea>'9') rea=getchar();
        while(rea>='0'&&rea<='9') x=x*10+rea-'0',rea=getchar();
    }
    const int N=10000006;
    
    int m,K;
    int dui[N+1000000],he,en;
    
    struct treap
    {
        int s,order,fix;
        treap *ch[2];
        treap(){}
        treap(int _order,int _s,int _fix)
        {
            order=_order; s=_s; fix=_fix;
            ch[0]=ch[1]=NULL;
        }
        treap(int _order,int _s)
        {
            order=_order; s=_s;
            fix=rand();
            ch[0]=ch[1]=NULL;
        }
    }*null,*root,tong[N*2];
    int size;
    void lturn(treap *&x)
    {
        treap *y=rs(x);
        rs(x)=ls(y); ls(y)=x; x=y;
        if(x!=null) s(x)=s(ls(x))+s(rs(x))+1;
        if(y!=null) s(y)=s(ls(y))+s(rs(y))+1;
    }
    void rturn(treap *&x)
    {
        treap *y=ls(x);
        ls(x)=rs(y); rs(y)=x; x=y;
        if(x!=null) s(x)=s(ls(x))+s(rs(x))+1;
        if(y!=null) s(y)=s(ls(y))+s(rs(y))+1;
    }
    treap* kth(int k)
    {
        treap *x=root; int tt;
        while(x!=null)
        {
            tt=s(ls(x))+1;
            if(tt==k) return x;
            if(tt<k) k-=tt,x=rs(x);
            else x=ls(x);
        }
        return null;
    }
    void add(int order,treap *&x)
    {
        if(order>m) return ;
        if(x==null)
        {
            tong[size]=treap(order,1);;
            x=&tong[size++];
            ls(x)=rs(x)=null;
            return ;
        }
        if(order<order(x))
        {
            add(order,ls(x));
            if(fix(ls(x))<fix(x))
                rturn(x);
        }
        else
        {
            add(order,rs(x));
            if(fix(rs(x))<fix(x))
                lturn(x);
        }
        if(x!=null) s(x)=s(ls(x))+s(rs(x))+1;
    }
    void del(int order,treap *&x)
    {
        if(order>m) return ;
        if(order==order(x))
        {
            if(ls(x)!=null&&rs(x)!=null)
            {
                if(fix(ls(x))<fix(rs(x)))
                {
                    rturn(x);
                    del(order,rs(x));
                }
                else
                {
                    lturn(x);
                    del(order,ls(x));
                }
            }
            else
            {
                if(ls(x)!=null) x=ls(x);
                else x=rs(x);
            }
        }
        else
            if(order<order(x))
                del(order,ls(x));
        else
            del(order,rs(x));
        if(x!=null) s(x)=s(ls(x))+s(rs(x))+1;
    }
    treap* build(int l,int r,int hi)
    {
        if(l>r) return null;
        int mid=(l+r)>>1;
        tong[size]=treap(mid,1,hi);
        treap *x=&tong[size++];
        ls(x)=build(l,mid-1,hi+1);
        rs(x)=build(mid+1,r,hi+1);
        return x;
    }
    
    bool ka[N],t[N];
    void workbb()
    {
        rint i,j;
        int now=0,op,tin,las=0;
        for(i=0;i<N;++i) t[i]=1;
        he=1; en=0;
        for(i=1;i<=m;++i)
        {
            read(op);
            if(op==1)
            {
                read(tin); if(K) tin^=las;
                ka[tin]=1; t[tin]=0;
                while(!t[now]) ++now;
            }
            else
                if(op==2)
                {
                    read(tin); if(K) tin^=las;
                    ka[tin]=0; t[tin]=1; dui[++en]=tin;
                    if(now>tin) now=tin;
                }
            else
                if(op==3)
                {
                    ka[dui[he]]=1; t[dui[he]]=0; ++he;
                    while(!t[now]) ++now;
                }
            else
                printf("%d
    ",now);
        }
    }
    
    set<int> se;
    void workbao()
    {
        rint i; int las=0,op,tin;
        he=1; en=0;
        
        for(i=0;i<=m;++i)    se.insert(i);
        
        for(i=1;i<=m;++i) 
        {
            read(op);
            if(op==1)
            {
                read(tin); if(K) tin^=las;
                if(tin<=m) se.erase(tin);
            }
            else
                if(op==2)
                {
                    read(tin); if(K) tin^=las;
                    if(tin<=m) se.insert(tin);
                    dui[++en]=tin;
                }
            else
                if(op==3)
                {
                    if(tin<=m) se.erase(dui[he]);
                    ++he;
                }
            else
                printf("%d
    ",*se.begin());
        }
    }
    
    void work()
    {
        rint i; int las=0,op,tin;
        null=&tong[size++];
        root=build(0,m,1);
        he=1; en=0;
        
        for(i=1;i<=m;++i) 
        {
            read(op);
            if(op==1)
            {
                read(tin); if(K) tin^=las;
                del(tin,root);
            }
            else
                if(op==2)
                {
                    read(tin); if(K) tin^=las;
                    add(tin,root);
                    dui[++en]=tin;
                }
            else
                if(op==3)
                    del(dui[he],root),++he;
            else
            {
                las=kth(1)->order;
                printf("%d
    ",las);
            }
        }
    }
    
    int main(){
        
        //freopen("T1.in","r",stdin);
        //freopen("T1.out","w",stdout);
        //freopen("knowledge.in","r",stdin);
        //freopen("knowledge.out","w",stdout);
        
        read(m); read(K);
        
        if(m<=1000)
            workbb();
        else
            if(m<=100000)
                workbao();
        else
            work();
        //fclose(stdin);
        //fclose(stdout);
    }
    T1treap
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <algorithm>
    #include <iostream>
    #include <queue>
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    #define rint register int
    using namespace std;
    inline void read(int &x)
    {
        x=0; char q=getchar();
        while(q<'0'||q>'9') q=getchar();
        while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar();
    }
    const int N=20000006;
    
    int m,K;
    int cnt=-1;
    bool flag[N];
    
    int dui[N],he,en;
    int dui1[N],he1,en1;
    
    int main(){
        
        //freopen("in.in","r",stdin);
        
        rint i; int op,tin,las=0;
        he=1; en=0; he1=1; en1=0;
        
        read(m); read(K);
        for(i=1;i<=m;++i)
        {
            read(op);
            if(op==1)
            {
                read(tin); if(K) tin^=las;
                flag[tin]=1;
                while(flag[cnt+1]) ++cnt;
            }
            else
                if(op==2)
                {
                    read(tin); if(K) tin^=las;
                    while(en>=he&&dui[en]>=tin) --en; dui[++en]=tin;
                    dui1[++en1]=tin;
                }
            else
                if(op==3)
                {
                    if(dui[he]==dui1[he1]) ++he;
                    ++he1;
                }
            else
                las=min(cnt+1,(en>=he?dui[he]:0x7fffffff)),printf("%d
    ",las);
        }
    }
    T1正解

    T2

    感觉好神啊...

    CF671D...

    $f_x$表示以x为根的子树里的树枝都被覆盖了,并且x到父亲的边也被覆盖了的最小花费

    那么考虑每一条链来更新$f_x$

    每一条经过x并覆盖x到父亲边的链都可以更新$f_x$

    那么这条链的底端点到x周围的儿子节点的f之和 以及 这条链的c 和$f_x$取min

    这个就用线段树优化

    注意特殊处理1节点

    ps.呆毛dp???...

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <algorithm>
    #include <iostream>
    #include <vector>
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    #define rint register int
    using namespace std;
    inline void read(int &x)
    {
        x=0; char q=getchar();
        while(q<'0'||q>'9') q=getchar();
        while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar();
    }
    const int N=300006;
    const ll Inf=1e15;
    int first[N],ver[N<<1],nt[N<<1],e;
    inline void addbian(int u,int v)
    {
        ver[e]=v;
        nt[e]=first[u];
        first[u]=e++;
    }
    
    int n,m;
    vector<int> tp[N],dw[N];
    int c[N],L[N],R[N],tim,pos[N];
    ll f[N];
    
    int fa[N];
    void dfs(int x)
    {
        int i,sz=dw[x].size();
        L[x]=tim+1;
        for(i=0;i<sz;++i)
            pos[dw[x][i]]=++tim;
        for(i=first[x];i!=-1;i=nt[i])
        {
            if(ver[i]==fa[x])
                continue;
            fa[ver[i]]=x;
            dfs(ver[i]);
        }
        R[x]=tim;
    }
    
    ll mn[N<<2],laz[N<<2];
    void pushdown(int x)
    {
        if(laz[x])
        {
            laz[x<<1]+=laz[x];
            laz[x<<1|1]+=laz[x];
            mn[x<<1]+=laz[x];
            mn[x<<1|1]+=laz[x];
            laz[x]=0;
        }
    }
    void build(int l,int r,int x)
    {
        mn[x]=Inf; laz[x]=0;
        if(l==r) return ;
        int mid=(l+r)>>1;
        build(l,mid,x<<1);
        build(mid+1,r,x<<1|1);
    }
    void add(int L,int R,ll vv,int l,int r,int x)
    {
        if(L>R) return ;
        if(L<=l&&r<=R)
        {
            mn[x]+=vv; laz[x]+=vv;
            return ;
        }
        pushdown(x);
        int mid=(l+r)>>1;
        if(L<=mid) add(L,R,vv,l,mid,x<<1);
        if(mid<R) add(L,R,vv,mid+1,r,x<<1|1);
        if(mn[x<<1]<mn[x<<1|1]) mn[x]=mn[x<<1];
        else mn[x]=mn[x<<1|1];
    }
    void modi(int pos,ll vv,int l,int r,int x)
    {
        if(l==r)
        {
            mn[x]=vv;
            return ;
        }
        pushdown(x);
        int mid=(l+r)>>1;
        if(pos<=mid) modi(pos,vv,l,mid,x<<1);
        else modi(pos,vv,mid+1,r,x<<1|1);
        if(mn[x<<1]<mn[x<<1|1]) mn[x]=mn[x<<1];
        else mn[x]=mn[x<<1|1];
    }
    void qq(int L,int R,ll &an,int l,int r,int x)
    {
        if(L>R) return ;
        if(L<=l&&r<=R)
        {
            if(an>mn[x]) an=mn[x];
            return ;
        }
        pushdown(x);
        int mid=(l+r)>>1;
        if(L<=mid) qq(L,R,an,l,mid,x<<1);
        if(mid<R) qq(L,R,an,mid+1,r,x<<1|1);
    }
    
    void dp(int x)
    {
        f[x]=Inf;
        ll sum=0; int i,sz;
        for(i=first[x];i!=-1;i=nt[i])
        {
            if(ver[i]==fa[x])    continue;
            dp(ver[i]);
            sum+=f[ver[i]];
            if(sum>Inf) sum=Inf;
        }
        if(x==1)
        {
            f[x]=sum;
            return ;
        }
        sz=dw[x].size();
        for(i=0;i<sz;++i)
            modi(pos[dw[x][i]],sum+c[dw[x][i]],1,m,1);
        sz=tp[x].size();
        for(i=0;i<sz;++i)
            modi(pos[tp[x][i]],Inf,1,m,1);
        for(i=first[x];i!=-1;i=nt[i])
            if(ver[i]!=fa[x])
                add(L[ver[i]],R[ver[i]],sum-f[ver[i]],1,m,1);
        qq(L[x],R[x],f[x],1,m,1);
    }
    
    int main(){
        
        //freopen("in.in","r",stdin);
        
        rint i,j;
        int tin1,tin2;
        
        mem(first,-1);
        
        read(n); read(m);
        for(i=1;i<n;++i)
        {
            read(tin1); read(tin2);
            addbian(tin1,tin2);
            addbian(tin2,tin1);
        }
        for(i=1;i<=m;++i)
        {
            read(tin1); read(tin2); read(c[i]);
            tp[tin2].push_back(i);
            dw[tin1].push_back(i);
        }
        dfs(1);
        build(1,m,1);
        dp(1);
        printf("%lld",(f[1]>=Inf?-1:f[1]));
    }
    T2

    T3

    留下了一个大坑...

    粘个标程吧...

    #include<cstdio>
    #include<algorithm>
    #define fo(i,a,b) for(i=a;i<=b;i++)
    using namespace std;
    typedef long long ll;
    const int maxn=1000000+10,maxnn=3000+10,mo=1000000007;
    int f[maxn],a[maxn],b[maxn],L[maxn],R[maxn],s[maxn],fac[maxn];
    int g[maxnn*2][maxnn*2][3];
    int i,j,k,l,r,t,n,m,ans,tmp,x,now;
    bool A,B,C;
    int read(){
      int x=0,f=1;
      char ch=getchar();
      while (ch<'0'||ch>'9'){
        if (ch=='-') f=-1;
        ch=getchar();
      }
      while (ch>='0'&&ch<='9'){
        x=x*10+ch-'0';
        ch=getchar();
      }
      return x*f;
    }
    bool cmp(int a,int b){
      return a>b;
    }
    int qsm(int x,int y){
      if (!y) return 1;
      int t=qsm(x,y/2);
      t=(ll)t*t%mo;
      if (y%2) t=(ll)t*x%mo;
      return t;
    }
    void prepare(){
      fac[0]=1;
      fo(i,1,n) fac[i]=(ll)fac[i-1]*i%mo;
      A=1;
      fo(i,1,n){
        L[i]=read();R[i]=read();
        if (i>1&&(L[i]!=L[i-1]||R[i]!=R[i-1])) A=0;
      }
      if (A){
        int ni=qsm(n+1,mo-2);
        l=L[1];r=R[1];
        fo(i,1,n) a[i]=(l+(ll)(r-l)*i%mo*ni%mo)%mo;
      }
      else{
        fo(i,1,n) a[i]=L[i];
        sort(a+1,a+n+1);
      }
    }
    void n2(){
      prepare();
      g[0][0][0]=1;
      fo(i,0,n+k-2)
        fo(j,0,i){
          (g[i+1][j][0]+=g[i][j][0])%=mo;//i+1 put 1
          if (i+1<=n) (g[i+1][j+1][0]+=g[i][j][0])%=mo;//i+1 put 0,not x
          if (i+1>=k){//x may pop
            if (i+1<=n){
              if (i+2-k>=j+1) (g[i+1][j+1][2]+=(ll)g[i][j][1]*b[i-k+2]%mo)%=mo;//i+1 put 0,x pop
              else (g[i+1][j+1][1]+=g[i][j][1])%=mo;//i+1 put 0,x not pop
            }
            if (i+2-k>=j) (g[i+1][j][2]+=(ll)g[i][j][1]*b[i-k+2]%mo)%=mo;//i+1 put 1,x pop
            else (g[i+1][j][1]+=g[i][j][1])%=mo;//i+1 put 1,x not pop
            if (i+1<=n){
              if (i+2-k>=j+1) (g[i+1][j+1][2]+=(ll)g[i][j][0]*b[i-k+2]%mo)%=mo;//i+1 put 0,is x,x pop
              else if (i+1<=n) (g[i+1][j+1][1]+=g[i][j][0])%=mo;//i+1 put 0,is x
            }
          }
          else{
            if (i+1<=n) (g[i+1][j+1][1]+=g[i][j][0])%=mo;//i+1 put 0,is x
            if (i+1<=n) (g[i+1][j+1][1]+=g[i][j][1])%=mo;//i+1 put 0
            (g[i+1][j][1]+=g[i][j][1])%=mo;//i+1 put 1
          }
          if (i+1>k){
            if (i+1<=n) (g[i+1][j+1][2]+=g[i][j][2])%=mo;//i+1 put 0
            (g[i+1][j][2]+=g[i][j][2])%=mo;//i+1 put 1
          }
        }
      fo(x,1,n){
        now=g[n+k-1][x][2];
        (ans+=(ll)now*fac[x-1]%mo*fac[n-x]%mo*a[x]%mo)%=mo;
      }
      ans=(ll)ans*qsm(fac[n],mo-2)%mo;
      (ans+=mo)%=mo;
      printf("%d
    ",ans);
    }
    int main(){
      //freopen("mouko10.in","r",stdin);freopen("mouko10.out","w",stdout);
      n=read();k=read();
      C=1;
      fo(i,1,n){
        b[i]=read();
        if (b[i]!=n-i+1) C=0;
      }
      if (!C){
        n2();
        return 0;
      }
      prepare();
      //sort(a+1,a+n+1,cmp);
      reverse(a+1,a+n+1);
      fo(i,1,n) s[i]=(s[i-1]+a[i])%mo;
      fo(i,1,k-1) (tmp+=(ll)a[i]*i%mo)%=mo;
      f[1]=a[1];
      fo(i,2,k)
        f[i]=((ll)f[i-1]*i%mo+(ll)fac[i]*a[i]%mo*i%mo)%mo;
      fo(i,k+1,n){
        f[i]=(ll)f[i-1]*i%mo;
        (f[i]+=(ll)fac[i-1]*k%mo*a[i]%mo*i%mo)%=mo;
        (f[i]+=(ll)fac[i-1]*((ll)(i-1+k)*(i-k)/2%mo)%mo*a[i]%mo)%=mo;
        t=(ll)(tmp+(ll)(s[i-1]-s[k-1])*(k-1)%mo)*fac[i-1]%mo;
        t=(f[i-1]-t)%mo;
        (f[i]+=t)%=mo;
      }
      ans=f[n];
      ans=(ll)ans*qsm(fac[n],mo-2)%mo;
      (ans+=mo)%=mo;
      printf("%d
    ",ans);
    }
     
    T3
  • 相关阅读:
    基本内置类型
    多维数组
    数组
    迭代器
    标准库类型 vector
    标准库类型 string
    运算符优先级表
    类型转换
    sizeof 和逗号运算符
    位运算符
  • 原文地址:https://www.cnblogs.com/A-LEAF/p/7751267.html
Copyright © 2020-2023  润新知