zoukankan      html  css  js  c++  java
  • noip近五年复习

    一.noip2018

    day 1

    T1 铺设道路

    13,18年通用入门题

    #define ll long long
    int n,a[100006];
    int main()
    {
        //freopen("in.txt","r",stdin);
        rd(n);
        int ans=0;
        inc(i,1,n)
        {
            rd(a[i]);
            if(a[i]>a[i-1])ans+=(a[i]-a[i-1]);
        }
        
        printf("%d",ans);
        re 0;
    }
    View Code

    当时我还写了好久,用了一种极其怪力的方法a了ta

    T2 货币系统

    完全背包嘛

    int n,a[100],vis[30000];
    int main()
    {
        //freopen("in.txt","r",stdin);
        int T;
        rd(T);
        while(T--)
        {
            rd(n);
            inc(i,1,n)rd(a[i]);
            memset(vis,0,sizeof vis);
            vis[0]=1;
            int ans=0;
            sort(a+1,a+n+1);
            inc(i,1,n)
            {
                if(!vis[a[i]])++ans;
                //vis[a[i]]=1;
                inc(j,a[i],a[n])
                vis[j]|=vis[j-a[i]];
            }
            printf("%d
    ",ans);
        }
        re 0;
    }
    View Code

    想当年,我可是全凭这道题爆搜的70pts,压线2=

    (说来惭愧……)

    T3 塞道修建

    这题思想还是较为简单,

    二分一下答案,在判断能否

    对于每个点将所有能配对的或自成一队的路径全部弄好

    将剩下中最长的路径返回参与父节点选拔

    就是stl用得伤心(因为要维护删除,所以迭代器随时要更新)

    /*
    user liangsiyi.
    language: c++
    */
    #include<bits/stdc++.h>
    #define re return
    #define st static
    #define Min(a,b) (a)>(b)?(b):(a)
    #define Max(a,b) (a)>(b)?(a):(b)
    #define mem(a,x) memset(a,x,sizeof(a))
    #define inc(i,l,r) for(register int i=l;i<=r;++i)
    #define dec(i,l,r) for(register int i=r;i>=l;--i)
    const int M=50000+5;
    using namespace std;
    int n,m,k,mid,flag=1,head[M],f[M],ff[M],s[M];
    template <typename T>inline void read(T &x)
    {
        bool f=0;char c;
        while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
        x=c^48;
        while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
        x=f==1?-x:x;
    }
    template <typename T>void put(const T x)
    {
        if(x>9)put(x/10);
        putchar((x%10)|48);
    }
    template<typename T>inline void write(const T x)
    {
        if(x<0)putchar('-'),put(-x);
        else put(x);
    }
    struct node
    {
        int to,nt,v;
    }e[M<<1];
    
    void add(int x,int y,int z)
    {
        e[++k].to=y;e[k].v=z;e[k].nt=head[x];head[x]=k;
        e[++k].to=x;e[k].v=z;e[k].nt=head[y];head[y]=k;
    }
    
    void dfs(int u,int fa)
    {
        f[u]=ff[u]=0;
        multiset<int>vi;
        for(int i=head[u];i;i=e[i].nt)
        {
            int v=e[i].to,w=e[i].v;
            if(v==fa)continue;
            dfs(v,u);                //可能会重复dfs(同一v)但u不同 ,结果不同 
            f[u]+=f[v];
            if(ff[v]+w>=mid)f[u]++;
            else vi.insert(ff[v]+w);
        }    
        while(!vi.empty())
        {
            multiset<int>::iterator i=vi.begin();
            int x=*i;vi.erase(i);
            multiset<int>::iterator y=vi.lower_bound(mid-x);
            if(y==vi.end())ff[u]=x;
            else {
                f[u]++;
                vi.erase(y);    
            }
        }
    }
    
    bool check()
    {    
        dfs(1,0);
        if(f[1]>=m)re 1;
        re 0;
        
    }
    bool check1()
    {
    
        f[1]=0;
        int l=1;
        dec(i,l,n-1)
        if(s[i]>=mid)f[1]++;
        else {
            while(s[i]+s[l]<mid&&l<i)l++;
            if(s[i]+s[l]>=mid&&l<i)f[1]++,l++;
            else break;
        }
        if(f[1]>=m)re 1;
        re 0;
        
    }
    
    int main()
    {
        
        int x,y,z,l=1e6,r=0;
        read(n);read(m);
        inc(i,1,n-1){
            read(x);read(y);read(z);
            add(x,y,z);    
            l=Min(l,z);r+=z;
            if(x!=1)flag=0;s[i]=z;
        }
        sort(s+1,s+n);
        
        if(flag)
        {
            while(l<=r)
            {
            mid=(l+r)>>1;
            if(check1())l=mid+1;
            else r=mid-1;
            }
        }
        else while(l<=r)
        {
            mid=(l+r)>>1;
            if(check())l=mid+1;
            else r=mid-1;
        }
        printf("%d",l-1);
        re 0;
    }
    View Code

    day 2

    T1 旅行

    基环树拆点

    发现基环树要么最大独立子集(强制枚举选与不选)

    要么在环上区间dp

    此题很显然,很暴力(毕竟是T1)

    #include<bits/stdc++.h>
    #define re return
    #define inc(i,l,r) for(int i=l;i<=r;++i) 
    using namespace std;
    template<typename T>inline void rd(T&x)
    {
        char c;bool f=0;
        while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
        x=c^48;
        while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
        if(f)x=-x;
    }
    
    const int maxn=5005;
    int n,m,hd[maxn];
    struct node{
        int to,nt;
    }e[maxn<<1];
    int k=1;
    inline void add(int x,int y){
        e[++k]=(node){y,hd[x]};hd[x]=k; 
    }
    
    
    namespace SOLU1{
        
        inline void dfs(int x,int fa)
        {
            printf("%d ",x);
            priority_queue<int,vector<int>,greater<int> >q;
            for(int i=hd[x];i;i=e[i].nt){
                int v=e[i].to;
                if(v!=fa)q.push(v);
            }
            while(!q.empty())
            {
                int v=q.top();q.pop();
                dfs(v,x);
            }
        }
        
    }
    
    namespace SOLU2{
        int bridge[maxn<<1],ban[maxn<<1],dfn[maxn],low[maxn],tot;
        inline void tarjan(int x,int E)
        {
            dfn[x]=low[x]=++tot;
            for(int i=hd[x];i;i=e[i].nt)
            {
                int v=e[i].to;
                if(i!=(E^1))
                {
                    if(!dfn[v])
                    {
                        tarjan(v,i);
                        if(low[v]>dfn[x])bridge[i]=bridge[i^1]=1;
                        else low[x]=min(low[x],low[v]);
                    }
                    else low[x]=min(low[x],dfn[v]);
                }
            }
        }
        
        int a[maxn],b[maxn],tot_a,flag;
        inline bool dfs(int x,int fa)
        {
            a[++tot_a]=x;
            if(x>b[tot_a]&&(!flag))re 0;
            else if(x<b[tot_a])flag=1;
            priority_queue<int,vector<int>,greater<int> >q;
            for(int i=hd[x];i;i=e[i].nt)
            {
                int v=e[i].to;
                if(v==fa||ban[i])continue;
                q.push(v);
            }
            while(!q.empty())
            {
                int v=q.top();q.pop();
                if(!dfs(v,x))re 0;
            }
            re 1;
        }
        
        inline void work()
        {
            inc(i,1,n)if(!dfn[i])tarjan(i,0);    
            inc(i,1,n)b[i]=n+1;
            
            for(int i=2;i<=k;i+=2)
            if(!bridge[i])
            {
                ban[i]=ban[i^1]=1;
                tot_a=0;flag=0;
                if(dfs(1,0))
                {
                    inc(i,1,n)b[i]=a[i];
                }
                ban[i]=ban[i^1]=0;
            }
            inc(i,1,n)
            printf("%d ",b[i]);
        }
    }
    
    int main()
    {
        freopen("in.txt","r",stdin);
        int x,y;
        rd(n),rd(m);
        inc(i,1,m)
        {
            rd(x),rd(y);
            add(x,y);
            add(y,x);
        }
        
        if(m==n-1)SOLU1::dfs(1,0);
        else SOLU2::work();
        re 0;
    } 
    View Code

    T2 填数游戏

    骗分过样例,打表出奇迹

    这道题是真~打表找规律的好题

    反正我今天只凹了65pts

    剩下的只要是不会暴力,不过在考场上要真的不会,最好还是弄一下这种题

    规律笔记比较好找

    int main()
    {
        rd(n),rd(m);
        if(n>m)swap(n,m);
        if(n==1)
        {
            printf("%lld",Pow(2ll,m));    
            re 0;
        }
        if(n<=3&&m<=3)
        {
            if(n==2){
                if(m==2)printf("12");
                else if(m==3)printf("36");
            }
            else printf("112"); 
            re 0;
        }
        if(n==2)
        {
            int now=m-1;
            printf("%lld",Pow(3,now)*4%P);
        }
        else if(n==3)
        {
            int now=m-3;
            printf("%lld",Pow(3,now)*112%P);
        }
        else{
            if(m == n)printf("%lld",(83*Pow(8,n)%P+5*Pow(2,n+7)%P)*190104168%P);
            else printf("%lld",(83*Pow(8,n)%P+Pow(2,n+8))*Pow(3,m-n-1)%P*570312504%P);
        }
        re 0;
    } 
    View Code

    T3 保卫王国

    ddp板子题

    毒瘤吧,wc才讲就考到noip中来

    只能暴力44pts(最大独立子集)

    A:44:

    const int maxn=2005;
    #define ll long long
    int n,m,p[maxn],hd[maxn];
    ll f[maxn][2],inf=999999999999;
    struct node{
        int to,nt;
    }e[maxn<<1];
    
    int k;
    inline void add(int x,int y){
        e[++k]=(node){y,hd[x]};hd[x]=k;
    }
    
    int limit[maxn];
    inline void dfs(int x,int fa){
        f[x][1]=p[x];
        f[x][0]=0;
        for(int i=hd[x];i;i=e[i].nt)     
        {
            int v=e[i].to;
            if(v==fa)continue;
            dfs(v,x);
            f[x][0]+=f[v][1];
            f[x][1]+=min(f[v][1],f[v][0]);
        }
        if(~limit[x])f[x][limit[x]]=inf;
    }
    int main()
    {
        freopen("in.txt","r",stdin);
        rd(n),rd(m);
        char GT[45];
        memset(limit,-1,sizeof limit);
        scanf("%s",GT);
        inc(i,1,n)rd(p[i]);
        int x,y,a,b;
        inc(i,2,n)
        {
            rd(x),rd(y);
            add(x,y),add(y,x);
        }
        inc(i,1,m)
        {
            rd(x),rd(a),rd(y);rd(b);
            limit[x]=a^1;
            limit[y]=b^1;
            dfs(1,0);
            ll ans=min(f[1][0],f[1][1]);
            if(ans>=inf)puts("-1");
            else printf("%lld
    ",ans);
            limit[x]=-1;
            limit[y]=-1;
        } 
        re 0;
    } 
    View Code

    B:100

    维护了一个直达链根的bot,树剖,寻常dp一下

    在建线段树的时候以重儿子为转移矩阵核心(分为重儿子与其他儿子两类),

    弄出一个关于矩阵的东西,加速和维护转移

          ret.s[0][0]=min(s[0][0]+a.s[0][0],s[0][1]+a.s[1][0]); 
            ret.s[0][1]=min(s[0][0]+a.s[0][1],s[0][1]+a.s[1][1]); 
            ret.s[1][0]=min(s[1][0]+a.s[0][0],s[1][1]+a.s[1][0]); 
            ret.s[1][1]=min(s[1][0]+a.s[0][1],s[1][1]+a.s[1][1]); 

    大概就是这个东西

    单点修改,再修改回来

    #include<bits/stdc++.h>
    #define re return
    #define inc(i,l,r) for(int i=l;i<=r;++i) 
    using namespace std;
    template<typename T>inline void rd(T&x)
    {
        char c;bool f=0;
        while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
        x=c^48;
        while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
        if(f)x=-x;
    }
    
    #define int long long
    const int maxn=1e5+5;
    int n,m,hd[maxn],p[maxn];
    struct node{
        int to,nt;
    }e[maxn<<1];
    int k;
    inline void add(int x,int y)
    {
        e[++k].to=y;e[k].nt=hd[x];hd[x]=k;
        e[++k].to=x;e[k].nt=hd[y];hd[y]=k;
    }
    
    int siz[maxn],son[maxn],fa[maxn];
    inline void dfs1(int x)
    {
        siz[x]=1;
        for(int i=hd[x];i;i=e[i].nt)
        {
            int v=e[i].to;if(v==fa[x])continue;
            fa[v]=x;dfs1(v);
            siz[x]+=siz[v];
            if(siz[v]>siz[son[x]])son[x]=v;
        }
    }
    int tot,seg[maxn],rev[maxn],top[maxn],bot[maxn];
    inline void dfs2(int x,int fp)
    {
        seg[x]=++tot;rev[tot]=x;
        top[x]=fp; 
        if(son[x])
        {
            dfs2(son[x],fp);bot[x]=bot[son[x]];
            for(int i=hd[x];i;i=e[i].nt)
                if(!top[e[i].to])dfs2(e[i].to,e[i].to);
        }
        else bot[x]=x;
    }
    int f[maxn][2];
    inline void dp(int x)
    {
        f[x][1]=p[x],f[x][0]=0;
        for(int i=hd[x];i;i=e[i].nt)
        {
            int v=e[i].to;
            if(e[i].to==fa[x])continue;
            dp(v);
            f[x][1]+=min(f[v][0],f[v][1]);
            f[x][0]+=f[v][1];
        }
    }
    
    //-------------------------
    struct Matrix{
        int s[2][2];
        inline Matrix operator*(Matrix a)const 
        {
            Matrix ret;
            ret.s[0][0]=min(s[0][0]+a.s[0][0],s[0][1]+a.s[1][0]); 
            ret.s[0][1]=min(s[0][0]+a.s[0][1],s[0][1]+a.s[1][1]); 
            ret.s[1][0]=min(s[1][0]+a.s[0][0],s[1][1]+a.s[1][0]); 
            ret.s[1][1]=min(s[1][0]+a.s[0][1],s[1][1]+a.s[1][1]); 
            re ret;
        }
    }t[maxn<<2],tmp[maxn],be[maxn];
    const int inf=2147483647;
    #define ls rt<<1
    #define rs rt<<1|1
    inline void build(int rt,int l,int r)
    {
        if(l==r)
        {
            int x=rev[l];
            int g1=f[x][1]-min(f[son[x]][0],f[son[x]][1]),g0=f[x][0]-f[son[x]][1];
            be[l]=tmp[l]=t[rt]=(Matrix){g1,g1,g0,inf};
            re ;
        }
        
        int mid=(l+r)>>1;
        build(ls,l,mid);
        build(rs,mid+1,r);
        t[rt]=t[ls]*t[rs];
    }
    
    inline Matrix query(int rt,int l,int r,int x,int y)
    {
        if(x<=l&&r<=y)
            re t[rt];
        int mid=(l+r)>>1;
        if(y<=mid)re query(ls,l,mid,x,y);
        else if(x>mid) re query(rs,mid+1,r,x,y);
        re query(ls,l,mid,x,y)*query(rs,mid+1,r,x,y);
    }
    
    inline void Modify(int rt,int l,int r,int pos)
    {
        if(l==r)
        {
            t[rt]=tmp[l];
            re ;
        }
        int mid=(l+r)>>1;
        if(pos<=mid)Modify(ls,l,mid,pos);
        else Modify(rs,mid+1,r,pos);
        t[rt]=t[ls]*t[rs];
    }
    
    inline Matrix Get_mat(int x){re query(1,1,n,seg[top[x]],seg[bot[x]]);}
    
    inline void modify(int x,int y)
    {
        if(y)tmp[seg[x]].s[0][0]=tmp[seg[x]].s[0][1]=inf;
        else tmp[seg[x]].s[1][0]=inf;
        while(x)
        {
            Matrix a=Get_mat(x);Modify(1,1,n,seg[x]);
            Matrix b=Get_mat(x);
            x=fa[top[x]];
            if(!x)re ;
             tmp[seg[x]].s[0][1]=(tmp[seg[x]].s[0][0]+=min(b.s[1][0],b.s[0][0])-min(a.s[1][0],a.s[0][0]));
             tmp[seg[x]].s[1][0]+=b.s[0][0]-a.s[0][0];
        }
    }
    
    inline void rebuild(int x)
    {
        while(x)
        {
            tmp[seg[x]]=be[seg[x]];
            Modify(1,1,n,seg[x]);
            x=fa[top[x]];
        }
    }
    #undef int
    int main()
    {
        #define int long long
    //    freopen("in.txt","r",stdin);
        int x,y;
        char TY[4];
        rd(n),rd(m);
        scanf("%s",TY);
        inc(i,1,n)rd(p[i]);
        inc(i,2,n)
        {
            rd(x),rd(y);
            add(x,y);
        }
        dfs1(1);dfs2(1,1);dp(1);build(1,1,n);
        
        int a,b;
        inc(i,1,m)
        {
            rd(a),rd(x),rd(b),rd(y);
            x^=1;y^=1;
            if(x&&y&&(fa[a]==b||fa[b]==a))puts("-1");
            else
            {
                modify(a,x);modify(b,y);
                Matrix ans=Get_mat(1);
                int now=min(ans.s[1][0],ans.s[0][0]);
                printf("%lld
    ",now); 
                rebuild(a);rebuild(b);        
            }
        }
        re 0;
    } 
    View Code

    简而言之,就是通过树链剖分弄成线段树,使用矩阵(及区间可加性)加速

    二.noip2017

    day 1

    T1 小凯的诱惑

    这打表,这规律找得

    我有50%是找不到这规律的

    #include<bits/stdc++.h>
    using namespace std;
    int main()
    {
        long long a,b;
        scanf("%lld%lld",&a,&b);
        printf("%lld",a*b-(a+b));
        return 0;
    } 
    View Code

    T2 时间复杂度 

     蓝题的模拟 可见这题有多恶心了

    #include<bits/stdc++.h>
    #define re return 
    #define st static
    #define mem(a,b) memset((a),(b),sizeof(a))
    #define Min(a,b) (a)<(b)?(a):(b)
    #define MAx(a,b) (a)>(b)?(a):(b)
    #define inc(i,l,r) for(int i=l;i<=r;++i)
    #define dec(i,l,r) for(int i=l;i>=r;--i)
    
    using namespace std;
    int z,n,t,w,vis[100],ins[100];
    string code[105],o;
    char c[105];
    
    int gm(int i)
    {
        if(code[i][z+1]=='n'){
            ++z;re 100000;    
        }
        int vv=0;
        while('0'<=code[i][z+1]&&code[i][z+1]<='9')vv=vv*10+(code[i][++z]-48);
         re vv;
    }
    
    int check()
    {
        stack<int>s;
        int flag=0,x,y,k,jj=0,jc=0,ans=0,cnt=0;
        
        for(int i=1;i<=n;++i)
        {
            if(c[i]=='F')
            {
                k=code[i][1]-'a'+1;
                if(vis[k])re -1;
                vis[k]=1;
                s.push(k);
                if(!flag)
                {
                    z=2;x=gm(i);
                    z++;y=gm(i);
                    if(x>y)flag=k;
                    else if(y-x>1000)
                    ins[k]=1,ans=max(ans,++cnt);
                }
            }
            else 
            {
                if(s.empty())re -1;
                k=s.top();s.pop();
                vis[k]=0;
                if(flag==k)flag=0;
                else if(ins[k])cnt--,ins[k]=0;
            }
        }
        if(!s.empty())re -1;
        re ans;
    }
    
    int go(int x)
    {
        int vv=0;
        while('0'<=o[x]&&o[x]<='9')vv=vv*10+(o[x++]-48);
        re vv;
    }
    
    int main()
    {
    //    freopen("in.txt","r",stdin);
        scanf("%d",&t);
        while(t--)
        {
            mem(vis,0);
            mem(ins,0);
            mem(c,0);
            int f=0;
            scanf("%d",&n);
            
            while(c[0]!='O')c[0]=getchar();
            getline(cin,o);
            if(o[1]=='n')f=1,w=go(3);
            else w=0;
    
            
            inc(j,1,n)
            {
                while(c[j]!=70&&c[j]!=69)c[j]=getchar();
                getline(cin,code[j]);            
            /*    inc(i,0,code[j].size())
                cout<<i<<" "<<code[j][i]<<endl;*/
            }    
            
            int ww=check();
    
    
            if(ww==-1)printf("ERR
    ");
            else if(ww==w)printf("Yes
    ");
            else printf("No
    ");
        }
    
        return 0;
    }
    View Code

    T3 逛公园

    day 2

    T1 奶酪

    只有一千个点,那就n^2的暴力+并查集判联通呗,

    #include<bits/stdc++.h>
    using namespace std;
    long long  t,n,h,r,u1,o1,r2;
    struct node
    {
    long long x,y,z;    
    }hollow[1505];
    int fa[1505];
    
    int find(long long x)
    {
        if(fa[x]==x)return x;
        fa[x]=find(fa[x]);
        return fa[x];
    }
     
    bool judge(long long i,long long j)
    {
        long long xx=abs(hollow[i].x-hollow[j].x),
            yy=abs(hollow[i].y-hollow[j].y),
            zz=abs(hollow[i].z-hollow[j].z);
        if(xx>r2||yy>r2||zz>r2)return 0;
        if(xx*xx+yy*yy+zz*zz>r2*r2)return 0;
        return 1;
    }
    int under[1001],over[1001];
    
    int main()
    {
        //freopen("pp.txt","r",stdin);
        //freopen("op.txt","w",stdout);
        scanf("%ld",&t);
        while(t>0)
        {
            memset(under,0,sizeof(under));
            memset(over,0,sizeof(over));
            scanf("%lld%lld%lld",&n,&h,&r);
            long long f=0;
            u1=o1=0;r2=2*r;t--;    
            for(long long i=1;i<=n;i++)
            {
            scanf("%lld%lld%lld",&hollow[i].x,&hollow[i].y,&hollow[i].z);
            if(hollow[i].z<=r)under[++u1]=i;
            if(h-hollow[i].z<=r)over[++o1]=i;    
            }
            
        
            for(long long i=1;i<=n;i++)
            fa[i]=i;
            
            for(long long i=1;i<=n;i++)
            for(long long j=i+1;j<=n;j++)
                {
                if(!judge(i,j))continue;
                fa[find(i)]=find(j);
                }
        
            for(long long i=1;i<=u1;i++)
            {
                for(int j=1;j<=o1;j++)
                if(find(under[i])==find(over[j]))
                {
                    f=1;
                    break;
                }
                if(f==1)break;
            }
            
         if(f==0)printf("No
    ");
            else printf("Yes
    ");
        }
        return 0;
    }
    View Code

    T2 宝藏

    仿佛记得机房某大佬有言:宝藏这个题本身就是一个宝藏

    因为其极其n<=12的特征

    所以理所当然不是暴力就是状压

    dfs|随机化|状压都是ok的

    然而我什么都不会…… 

    70pts的dfs

    #include<bits/stdc++.h>
    #define re return
    #define inc(i,l,r) for(int i=l;i<=r;++i)
    using namespace std;
    template<typename T>inline void rd(T&x)
    {
        char c;bool f=0;
        while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
        x=c^48;
        while((c=getchar())>='0'&&c<='9')x=x*10+(c^48) ;
        if(f)x=-x;
    }
    
    int n,m,d[20][20],dis[20];
    int inf=555555555,ans=inf;
    inline void dfs(int dep,int sum)
    {
        if(sum>ans)re ;
        if(dep==n+1){
            if(ans==51&&sum<ans)
            ans=sum;
            ans=sum;
            re ;
        }
        inc(i,1,n)
        if(dis[i])
        {
            inc(j,1,n)
            if(!dis[j]&&d[i][j]!=inf)
            {
                dis[j]=dis[i]+1;
                dfs(dep+1,sum+dis[i]*d[i][j]);
                dis[j]=0;
            }
        }
    }
    int main()
    {
        freopen("a.in","r",stdin);
        int x,y,z;
        rd(n),rd(m);
        inc(i,1,n)inc(j,1,n)d[i][j]=inf;
        inc(i,1,n)d[i][i]=0;
        inc(i,1,m)
        {
            rd(x),rd(y),rd(z);
            d[x][y]=d[y][x]=min(d[y][x],z);
        } 
    /*    inc(k,1,n)inc(i,1,n)inc(j,1,n)
        d[i][j]=min(d[i][j],d[i][k]+d[k][j]);*/
        
        inc(i,1,n)
        {
            dis[i]=1;
            dfs(2,0);
            dis[i]=0;
        }
        printf("%d",ans) ;
        re 0;
    }
    View Code

    T3 队列

    正解树状数组不会

    写过又臭又长的splay

    当然最好还是权值线段树

    #include<bits/stdc++.h>
    #define re return
    #define inc(i,l,r) for(int i=l;i<=r;++i)
    using namespace std;
    template<typename T>inline void rd(T&x)
    {
        char c;bool f=0;
        while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
        x=c^48;
        while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
        if(f)x=-x;
    }
    
    #define ll long long
    const int maxn=3e5+5;
    ll n,m,Q;
    ll T[maxn],ls[maxn<<5],rs[maxn<<5],num[maxn<<5];
    ll use[maxn<<5];
    
    ll tot,ans,flag;
    inline void query(ll &rt,ll l,ll r,ll x)
    {
        if(!rt)
        rt=++tot;
            ++use[rt];
        if(l==r)
        {
            if(num[rt])ans=num[rt];
            else if(!flag)ans=m*l;
            else ans=(flag-1)*m+l; 
            re ;
        }
        int mid=(l+r)>>1;
        int cnt=mid-l+1-use[ls[rt]];
         if(cnt>=x)query(ls[rt],l,mid,x);
         else query(rs[rt],mid+1,r,x-cnt);
    }
    
    inline void insert(ll &rt,ll l,ll r,ll pos)
    {
        if(!rt)rt=++tot;
        if(l==r)
        {
            num[rt]=ans;
            re ;
        }
        ll mid=(l+r)>>1;
        if(pos<=mid)insert(ls[rt],l,mid,pos);
        else insert(rs[rt],mid+1,r,pos);
    }
    
    ll sum[maxn];
    int main()
    {
        freopen("b.in","r",stdin);
        ll x,y;
        rd(n),rd(m),rd(Q);
        inc(i,1,Q)
        {
            rd(x),rd(y);
            if(y==m)
            {
                flag=0;
                query(T[n+1],1,n+Q,x);
                printf("%lld
    ",ans);
                ++sum[n+1];
                insert(T[n+1],1,n+Q,sum[n+1]+n);
            }
            else
            {
                flag=x;
                query(T[x],1,m+Q,y);
                printf("%lld
    ",ans);
                ++sum[n+1];
                insert(T[n+1],1,n+Q,sum[n+1]+n);
                
                flag=0;
                query(T[n+1],1,n+Q,x);
                ++sum[x];
                insert(T[x],1,m+Q,sum[x]+m-1);
            }
        }
        re 0;
    }
    View Code

    三.noip2016

    day 1

    T1 玩具谜题

    zz模拟

    #include<bits/stdc++.h>
    #define re return
    #define inc(i,l,r) for(int i=l;i<=r;++i)
    using namespace std;
    template<typename T>inline void rd(T&x)
    {
        char c;bool f=0;
        while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
        x=c^48;
        while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
        if(f)x=-x;
    }
    
    #define dec(i,l,r) for(int i=l;i>=r;--i)
    int n,m,f[100005];
    string s[100005];
    int main()
    {
        freopen("b.in","r",stdin);
        rd(n),rd(m);
        inc(i,1,n)
        {
            rd(f[i]);
            cin>>s[i];
        }
        
        int now=1,x,y;
        inc(i,1,m)
        {
            rd(x),rd(y);
            if(!x)//左数 
            {
                if(f[now])
                {
                    now+=y;
                    if(now>n)now-=n;
                }
                else
                {
                    now-=y;
                    if(now<=0)now+=n;
                } 
            }
            else 
            {
                if(f[now])
                {
                    now-=y;
                    if(now<=0)now+=n;
                }
                else{
                    now+=y;
                    if(now>n)now-=n;
                }
            }
        }
        
        cout<<s[now];
        re 0;
    }
    View Code

    T2 天天爱跑步

    全场最难的题竟然放到了day1t2

    有毒

    估计也就只能骗部分分了

    #include<bits/stdc++.h>
    #define re return
    #define inc(i,l,r) for(int i=l;i<=r;++i)
    using namespace std;
    template<typename T>inline void rd(T&x)
    {
        char c;bool f=0;
        while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
        x=c^48;
        while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
        if(f)x=-x;
    }
    
    const int maxn=300005,maxz=600000,maxl=300000;
    int n,m,k,hd[maxn],ans[maxn],val[maxn];
    struct node
    {
        int to,nt;
    }e[maxn<<1];
    
    inline void add(int x,int y)
    {
        e[++k].to=y;e[k].nt=hd[x];hd[x]=k;
        e[++k].to=x;e[k].nt=hd[y];hd[y]=k;
    }
    
    struct solu{
        //分为s,t两部分
        int top,tot,cnt;
        int rt[maxn*30],sum[maxn*30][2],ls[maxn*30],rs[maxn*30],first[maxn];
        int rab[maxn*30];
        struct ll{
            int flag,op,val,nt;
        }st[maxn<<2];
        
        inline void insert(int x,int y,int z,int f)
        {
            st[++top]=(ll){f,z,y,first[x]};
            first[x]=top;
        }
        
        
        inline int New()
        {
            int now;
            if(tot)now=rab[tot--];
            else now=++cnt;
            ls[now]=rs[now]=sum[now][0]=sum[now][1]=0;
            re now;
        }
        inline void Throw(int x)
        {
            rab[++tot]=x;
        }
        
         
        inline int query(int rt,int l,int r,int pos,int f)
        {
            if(!rt)re 0;
            if(l==r)
                re sum[rt][f];
            int mid=(l+r)>>1;
            if(pos<=mid)re query(ls[rt],l,mid,pos,f);
            else re query(rs[rt],mid+1,r,pos,f);
        }
        
        inline void add(int &rt,int l,int r,int pos,int vvl,int f)
        {
            if(!rt) rt=New();
            if(l==r)
            {
                sum[rt][f]+=vvl;
                re ;
            }
            int mid=(l+r)>>1;
            if(pos<=mid)add(ls[rt],l,mid,pos,vvl,f);
            else add(rs[rt],mid+1,r,pos,vvl,f);
        }
        
        inline int merge(int x,int y,int l,int r)
        {
            if(!x||!y)re x+y;
            if(l==r)
            {
    
                sum[x][0]+=sum[y][0];
                sum[x][1]+=sum[y][1];
                Throw(y);
                re x;
            }
            
            int mid=(l+r)>>1;
            
            ls[x]=merge(ls[x],ls[y],l,mid);
            rs[x]=merge(rs[x],rs[y],mid+1,r);
            Throw(y);
            re x;
        }
    }T;
    
    struct Tree_lca
    {
        int top[maxn],size[maxn],son[maxn],dep[maxn],fa[maxn];
        
        inline void dfs(int x)
        {
            dep[x]=dep[fa[x]]+(size[x]=1);
            for(int i=hd[x];i;i=e[i].nt)
            {
                int v=e[i].to;
                if(v!=fa[x])
                {
                    fa[v]=x;
                    dfs(v);
                    size[x]+=size[v];
                    if(size[v]>size[son[x]])son[x]=v;
                }
            }
        }
        
        inline void dfs2(int x,int topf)
        {
            top[x]=topf;
            if(son[x])
            {
                dfs2(son[x],topf);
                for(int i=hd[x];i;i=e[i].nt)
                {
                    int v=e[i].to;
                    if(!top[v])
                    dfs2(v,v);
                }
            }
        }
        
        inline int Lca(int x,int y)
        {
            while(top[x]!=top[y])
            {
                if(dep[top[x]]<dep[top[y]])x^=y^=x^=y;
                x=fa[top[x]];
            }
            re dep[x]<dep[y]?x:y;
        }
            
    }S;
    
    inline void dfs(int x)
    {
        for(int i=hd[x];i;i=e[i].nt)
        {
            int v=e[i].to;
            if(v!=S.fa[x])
            {
                dfs(v);
                if(x==1&&v==2)
                x=1; 
                T.rt[x]=T.merge(T.rt[x],T.rt[v],1,maxz);
            }
        }
    
        for(int i=T.first[x];i;i=T.st[i].nt)
            T.add(T.rt[x],1,maxz,T.st[i].val,T.st[i].op,T.st[i].flag);
        
        ans[x]=T.query(T.rt[x],1,maxz,S.dep[x]+val[x]+maxl,0);
        ans[x]+=T.query(T.rt[x],1,maxz,val[x]-S.dep[x]+maxl,1);
        
    }
    
    int main()
    {
    //    freopen("in.txt","r",stdin);
        int x,y,z;
        rd(n),rd(m);
        inc(i,2,n)
        {
            rd(x),rd(y);
            add(x,y); 
        }
        
        S.dfs(1);
        S.dfs2(1,n+1); 
        
        inc(i,1,n)
        rd(val[i]);
        
        inc(i,1,m)
        {
            rd(x),rd(y);
            int lca=S.Lca(x,y),flca=S.fa[lca];
            T.insert(x,S.dep[x]+maxl,1,0);T.insert(flca,S.dep[x]+maxl,-1,0);
            T.insert(y,S.dep[x]-(S.dep[lca]<<1)+maxl,1,1);T.insert(lca,S.dep[x]-(S.dep[lca]<<1)+maxl,-1,1);        
        }
        dfs(1);
        
        inc(i,1,n)
        printf("%d ",ans[i]);
        re 0;
    }
    View Code

    T3换教室

    遇到概率妥妥挂掉

    呃……

    虽然是模板题

    #include<bits/stdc++.h>
    #define re return
    #define inc(i,l,r) for(long long i=l;i<=r;++i) 
    using namespace std;
    template<typename T>inline void rd(T&x)
    {
        char c;bool f=0;
        while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
        x=c^48;
        while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
        if(f)x=-x;
    }
    
    const int maxn=2005;
    
    #define ll long long 
    ll n,m,v,e;
    ll mp[maxn][maxn],c[maxn],d[maxn];
    double f[maxn][maxn][2],p[maxn];
    
    inline void floyd()
    {
        inc(k,1,v)
        inc(i,1,v)
        inc(j,1,v)
            mp[i][j]=min(mp[i][j],mp[i][k]+mp[k][j]);
        
    }
    
    int main()
    {
        
    //    freopen("in.txt","r",stdin);    
        rd(n),rd(m),rd(v),rd(e);
        ll x,y,z;
        
        inc(i,1,n)rd(c[i]);
        inc(i,1,n)rd(d[i]);
        inc(i,1,n)scanf("%lf",&p[i]);
        memset(mp,0x3f3f3f3f,sizeof mp);
        inc(i,1,v)mp[i][i]=0;
        inc(i,1,e)
        {
            rd(x),rd(y);
            rd(z);
            mp[x][y]=mp[y][x]=min(mp[x][y],z);
        }
        
        inc(i,1,n)inc(j,0,m)f[i][j][1]=f[i][j][0]=21174444;
        f[1][0][0]=0;
        f[1][1][1]=0;
        floyd();
        inc(i,2,n)
        inc(j,0,m)
        {
            f[i][j][0]=min(f[i-1][j][0]+mp[c[i-1]][c[i]],f[i-1][j][1]+(1-p[i-1])*mp[c[i-1]][c[i]]+p[i-1]*mp[d[i-1]][c[i]]);
            
            if(j)f[i][j][1]=min(f[i-1][j-1][0]+(1-p[i])*mp[c[i-1]][c[i]]+p[i]*mp[c[i-1]][d[i]],
                        f[i-1][j-1][1]+(1-p[i])*(1-p[i-1])*mp[c[i-1]][c[i]]
                        +p[i-1]*(1-p[i])*mp[d[i-1]][c[i]]+(1-p[i-1])*p[i]*mp[c[i-1]][d[i]]+p[i-1]*p[i]*mp[d[i-1]][d[i]]);
        }
        
        double ans=2147483647;
        inc(i,0,m)
        ans=min(ans,min(f[n][i][0],f[n][i][1]));
        printf("%.2lf",ans);
        re 0;
    } 
    View Code

      

    day 2

    T1 组合数问题

    #include<bits/stdc++.h>
    #define re return
    #define inc(i,l,r) for(int i=l;i<=r;++i)
    using namespace std;
    template<typename T>inline void rd(T&x)
    {
        char c;bool f=0;
        while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
        x=c^48;
        while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
        if(f)x=-x;
    }
    
    #define dec(i,l,r) for(int i=l;i>=r;--i)
    const int maxn=2005;
    int n,m,k,P,sum[maxn][maxn],c[maxn][maxn];
    
    int main()
    {
    //    freopen("b.in","r",stdin);
        int T;
        rd(T);rd(P);
        c[0][0]=1;
        c[1][1]=c[1][0]=1;
        inc(i,2,2000)
        {
            c[i][0]=1;
            inc(j,1,i)
            {
                c[i][j]=(c[i-1][j-1]+c[i-1][j])%P;
                sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+(c[i][j]==0);
            }
            sum[i][i+1]=sum[i][i];
        }
        int x,y;
        while(T--)
        {
            rd(x),rd(y);
            if(y>x)y=x;
            printf("%d
    ",sum[x][y]);
        } 
        re 0;
    }
    View Code

    T2 蚯蚓

    三个优队的故事

    #include<bits/stdc++.h>
    #define re return
    #define dec(i,l,r) for(int i=l;i>=r;--i)
    #define inc(i,l,r) for(int i=l;i<=r;++i)
    using namespace std;
    template<typename T>inline void rd(T&x)
    {
        char c;bool f=0;
        while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
        x=c^48;
        while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
        if(f)x=-x;
    }
    const int maxn=1e5+5;
    #define ll long long
    queue<ll>q1,q2,q3;
    ll n,m,q,u,v,t,a[maxn],c[8000005];
    double p;
    inline ll Get_max()
    {
        ll na,nb,nc;
        na=nb=nc=-99999999999999999;
        if(!q1.empty())na=q1.front();
        if(!q2.empty())nb=q2.front();
        if(!q3.empty())nc=q3.front();
        if(na>nb)
        {
            if(na>nc){q1.pop();re na;}
            else {q3.pop();re nc;}
        }
        else
        {
            if(nb>nc) {q2.pop();re nb;}
            else {q3.pop();re nc;}
        }
    }
    int main()
    {
    //  freopen("in.txt","r",stdin);
        scanf("%lld%lld%lld%lld%lld%lld",&n,&m,&q,&u,&v,&t);
        p=1.0*u/v;;
        inc(i,1,n)
        {
            rd(a[i]);
        }
        sort(a+1,a+n+1);
        dec(i,n,1)q1.push(a[i]);
    
        ll ic=0;
        inc(i,1,m)
        {
            ll T=Get_max();
            T+=ic;
            if(!(i%t))printf("%lld ",T);
            ic+=q;
            ll ta=(((int)(T*p))-ic);
            ll tb=(T-((int)(T*p)))-ic;
            if(ta>tb)
            swap(ta,tb);
            q2.push(tb);
            q3.push(ta);
        }
    
        printf("
    ");
        int cnt=0;  
        while(!q1.empty())c[++cnt]=q1.front(),q1.pop();
        while(!q2.empty())c[++cnt]=q2.front(),q2.pop();
        while(!q3.empty())c[++cnt]=q3.front(),q3.pop();
        sort(c+1,c+cnt+1);
        inc(i,1,(n+m)/t)
        {
            printf("%lld ",c[n+m-i*t+1]+ic);
        }
        re 0;
    } 
    View Code

     T3 愤怒的小鸟

    数据很小,状压

    先处理出最多n^2的线

    当然还阔以随机化

    #include<bits/stdc++.h>
    #define re return
    #define st static
    #define C  c=getchar()
    #define mem(a,b) memset((a),(b),sizeof(a))
    #define inc(i,l,r) for(int i=l;i<=r;++i)
    #define dec(i,l,r) for(int i=l;i>=r;--i)
    const double EPS=1e-9;
    
    template<typename T>inline void read(T&x)
    {
        char c;bool f=0;
        while((C)<'0'||c>'9')if(c=='-')f=1;
        x=c^48;
        while((C)>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48);
        if(f)x=-x;
    }
    
    using namespace std;
    
    int t,n,m,best=0x3f3f3f3f,vis[20],mp[20];
    
    double a,b;
    struct node
    {
        double x,y;
    }e[20];
    
    void cala(double x1,double y1,double x2,double y2)
    {
        a=(y1*x2-y2*x1)/(x1*x2*(x1-x2));
        b=(y1-a*x1*x1)/x1;
    }
    
    
    int main()
    {
    //    freopen("in.txt","r",stdin);
        
        srand(time(NULL));
        inc(i,1,20)
        mp[i]=1<<(i-1);
        
        read(t);
        while(t--)
        {
            best=0x3f3f3f3f;
            read(n),read(m);
        
            for(int i=1;i<=n;i++)scanf("%lf%lf",&e[i].x,&e[i].y);
            
            inc(zz,1,60)
            {
                mem(vis,0);
                random_shuffle(e+1,e+n+1);
                
                int ans=0;
                inc(i,1,n)
                {
                    if(vis[i])continue;
                    vis[i]=1;    
                    inc(j,i+1,n)
                    {
                        if(vis[j])continue;
                        if(e[i].x==e[j].x)continue;
                         b=(e[i].y-e[j].y*(e[i].x*e[i].x)/(e[j].x*e[j].x))/(e[i].x-(e[i].x*e[i].x)/e[j].x);
                         a=(e[i].y-e[i].x*b)/(e[i].x*e[i].x);
                        if(a>=-EPS)continue;
                        vis[j]=1;
                        inc(k,j+1,n)if(fabs(e[k].y-a*e[k].x*e[k].x-b*e[k].x)<EPS)vis[k]=1;
                        break;
                    }
                    ans++;
                }
                best=min(best,ans);
                if(best==1)break;
            }    
            printf("%d
    ",best);
        }
        
        re 0;
    } 
    View Code

    每次枚举时,枚举一下当前未包含的点

    #include<bits/stdc++.h>
    #define re return
    #define st static
    #define C  c=getchar()
    #define mem(a,b) memeset((a),(b),sizeof(a))
    #define inc(i,l,r,c) for(int i=l;i<=r;i+=c)
    #define dec(i,l,r,c) for(int i=l;i>=r;i-=c)
    const double EPS=1e-6;
    
    template<typename T>inline void read(T&x)
    {
        char c;bool f=0;
        while((C)<'0'||c>'9')if(c=='-')f=1;
        x=c^48;
        while((C)>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48);
        if(f)x=-x;
    }
    
    using namespace std;
    int t,n,m,dp[1<<20],vmp[1<<20],line[20][20];
    double a,b,x[20],y[20];
    
    void cala(double x1,double y1,double x2,double y2)
    {
        a=(y1*x2-y2*x1)/(x1*x2*(x1-x2));
        b=(x1*x1*y2-x2*x2*y1)/(x1*x2*(x1-x2));
    }
    
    
    int main()
    {
    //    freopen("in.txt","r",stdin);
        for(int i=0;i<(1<<18);i++){ int j=1;for(;j<=18 && i&(1<<(j-1));j++);vmp[i]=j;}
        for(int i=1;i<=18;i++)line[i][0]=1<<(i-1);
        read(t);
        while(t--)
        {
            read(n),read(m);
            int ALL=(1<<n)-1;
            for(int i=1;i<=ALL;i++)dp[i]=1111111111;
            inc(i,1,n,1)inc(j,1,n,1)line[i][j]=0;
            
            int cnt=0;
            for(int i=1;i<=n;i++)scanf("%lf%lf",&x[i],&y[i]);
            
            for(int i=1;i<=n;++i)
            {
                for(int j=1;j<=n;++j)
                {    
                    if(x[i]==x[j])continue;
                    cala(x[i],y[i],x[j],y[j]);
                    if(a>=0)continue;
                    
                    for(int k=1;k<=n;++k)
                        if(fabs(y[k]-a*x[k]*x[k]-b*x[k])<EPS)line[i][j]|=line[k][0];                
                }
            }
                
            
            for(int i=0;i<(1<<n);i++)
            {
                int j=vmp[i];
                for(int k=0;k<=n;k++)
                    dp[i|line[j][k]]=min(dp[i|line[j][k]],dp[i]+1);
            }
            
            printf("%d
    ",dp[(1<<n)-1]);
        }
        re 0;
    } 
    View Code

    四.noip2015

    day 1

     T1 神奇的幻方

    按照说的做

    #include<bits/stdc++.h>
    #define re return
    #define inc(i,l,r) for(int i=l;i<=r;i++)
    #define dec(i,l,r) for(int i=l;i>=r;i--)
    
    template<typename T>inline void read(T&x)
    {
        char c;bool f=0;
        while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
        x=c^48;
        while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
        if(f)x=-x;
    }
    
    using namespace std;
    int n,a[50][50];
    
    int main()
    {
        read(n);
        int v=1,x=1,y=(n+1)>>1,z=n*n;a[x][y]=1;
        while(++v<=z)
        {
            if(x==1&&y!=n)x=n,y++;
            else if(x!=1&&y==n)x--,y=1;
            else if(x==1)x++;
            else 
            {
                if(!a[x-1][y+1])x--,y++;
                else x++;
            }
            if(x>n)x=1;
            if(y>n)y=1;
            a[x][y]=v;
        }
        
        inc(i,1,n)
        {
            inc(j,1,n)printf("%d ",a[i][j]);
            putchar('
    ');
        }
        re 0;
    }
    View Code

    T2 信息传递

    找最小环

    #include<bits/stdc++.h> 
    #define re return
    #define inc(i,l,r) for(int i=l;i<=r;++i)
    using namespace std;
    template<typename T>inline void rd(T&x)
    {
        char c;bool f=0;
        while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
        x=c^48;
        while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
        if(f)x=-x; 
    } 
    
    const int maxn=2e5+5;
    int n,m,d[maxn],hd[maxn];
    struct node{
        int to,nt;
    }e[maxn<<1];
    int k;
    inline void add(int x,int y){e[++k]=(node){y,hd[x]};hd[x]=k;++d[y];}
    
    int c[maxn];
    inline void topo()
    {
        queue<int>q;
        inc(i,1,n)if(!d[i])q.push(i) ;
        while(!q.empty())
        {
            int x=q.front();
            c[x]=1;
            q.pop();
            for(int i=hd[x];i;i=e[i].nt)
            {
                int v=e[i].to;
                if(!(--d[v]))q.push(v);
            }
        }
    }
    int cnt,ans;
    inline void dfs(int x)
    {
        if(c[x])re ;
        c[x]=1;++cnt;
        for(int i=hd[x];i;i=e[i].nt)
        {
            int v=e[i].to;
            dfs(v);
        }
    }
    int main()
    {
        freopen("b.in","r",stdin);
        rd(n);
        int x;
        inc(i,1,n)
        {
            rd(x);
            add(i,x);
        }
        topo();
        
        ans=n;    
        inc(i,1,n)
        if(!c[i])
        {
            cnt=0;
            dfs(i);
            ans=min(ans,cnt);
        }    
        
        printf("%d",ans);
        re 0;
    }
    View Code

    T3 斗地主

    玄学的搜索

    #include<bits/stdc++.h>
    #define re return
    #define st static
    #define inc(i,l,r) for(int i=l;i<=r;++i)
    #define dec(i,l,r) for(int i=l;i>=r;--i)
    
    template<typename T>inline void read(T&x)
    {
        char c;bool f=0;
        while((c=getchar())<'0'||c>'9')if(c=='-')c=getchar();
        x=c^48;
        while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
        if(f)x=-x;
    }
    
    using namespace std;
    int a[20],t,n,ans;
    
    void doudizhu(int x)
    {
        if(x>ans)re;
        
        int k=0; 
        inc(i,3,14)//单顺子 
        if(!a[i])k=0;
        else
        {
            k++;
            if(k>=5)
            {
                inc(j,0,k-1)a[i-j]--;
                doudizhu(x+1);
                inc(j,0,k-1)a[i-j]++;    
            }    
        }
        
        k=0;
        inc(i,3,14)//双顺子
        if(a[i]<=1)k=0; 
        else 
        {
            k++;
            if(k>=3)
            {
                inc(j,0,k-1)a[i-j]-=2;
                doudizhu(x+1);
                inc(j,0,k-1)a[i-j]+=2;
            }
        }
        
        k=0;
        inc(i,3,14)//三顺子
        if(a[i]<=2)k=0; 
        else 
        {
            k++;
            if(k>=2)
            {
                inc(j,0,k-1)a[i-j]-=3;
                doudizhu(x+1);
                inc(j,0,k-1)a[i-j]+=3;
            }
        }
    //------------------------------------------------------------------------------------------------------------------------------
    
        inc(i,2,14)
        {
            if(a[i]==4)//四带 
            {
                a[i]-=4;    
                
            
                inc(j,2,14)
                if(a[j]>=2)
                {
                    a[j]-=2;
                    inc(z,2,14)
                    {
                        if(a[z]>=2)
                        {
                            a[z]-=2;
                            doudizhu(x+1);
                            a[z]+=2;
                        }
                    }
                    a[j]+=2;
                }
                
                      
               inc(j,2,15)   //四带二 
               {
                   if(!a[j])continue;
                   a[j]--;
                   inc(z,2,15)
                   if(a[z])
                   {
                       a[z]--;
                       doudizhu(x+1);
                       a[z]++;
                   }
                   a[j]++;    
               } 
                
                doudizhu(x+1);
                a[i]+=4;
            }
            if(a[i]>=3)//三带 
            {
                a[i]-=3;
                inc(j,2,14)
                if(a[j]>=2)//三带二 
                {
                a[j]-=2;    
                doudizhu(x+1);
                a[j]+=2;    
                }
            
                inc(j,2,15)
                if(a[j]&&j!=i)//三带一 
                {
                    a[j]--;
                    doudizhu(x+1);
                    a[j]++;
                }
                doudizhu(x+1);
                a[i]+=3;
            }
        }    
    //------------------------------------------------------------------------------------------------------------------------
        inc(i,2,15)if(a[i])x++;
        ans=min(ans,x);
    }
    
    
    void vcc()
    {
        int x,y;
        ans=23;
        memset(a,0,sizeof(a));
        inc(i,1,n)
        {
            read(x),read(y);
            if(!x)a[15]++;
            else if(x==1)a[14]++;
            else a[x]++;
        }
        doudizhu(0);
        printf("%d
    ",ans);
    }
    int main()
    {
    //    freopen("testdata(1).in","r",stdin);
        
      /*  freopen("in.txt","r",stdin);*/
        read(t),read(n);
        while(t--)vcc();
        re 0;
    }
    View Code

    day 2

    T1 跳石头

    贪心+二分

    #include<bits/stdc++.h>
    #define re return
    #define sta static
    #define supervisor liangsiyi.mz
    #define inc(i,l,r) for(int i=l;i<=r;++i) 
    #define dec(i,l,r) for(iny i=l;i>=r;--i)
    
    using namespace std;
    int n,k,l=1,r,m,ll,size,a[50005];
    
    inline int read()
    {
        int date=0;char c=' ';
        while('0'>c||c>'9')c=getchar();
        while('0'<=c&&c<='9'){date=(date<<3)+(date<<1)+(c^48);c=getchar();}
        re date;
    }
    
    bool jd(int floor)
    {
        int tot=0,now=0;
        inc(i,1,n+1)
        if(a[i]-a[now]<floor)tot++;
        else now=i;
        
        if(tot<=m)re 1;
        else re 0;
    }
    
    int main()
    {
        ll=read(),n=read(),m=read();
    
        inc(i,1,n)
            a[i]=read();
            a[n+1]=ll;
            if(n-m==0)r=ll;
        else r=ll/(n-m)+1;
        while(l<=r)
        {
            int mid=(l+r)/2;
            if(jd(mid))l=mid+1;
            else r=mid-1;
        }
        
        printf("%d",l-1);
        
        re 0;
    }
    View Code

    T2 子串

    dp

    去年奇奇怪怪地写了过去

    #include<bits/stdc++.h> 
    #define re return
    #define inc(i,l,r) for(int i=l;i<=r;++i)
    using namespace std;
    template<typename T>inline void rd(T&x)
    {
        char c;bool f=0;
        while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
        x=c^48;
        while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
        if(f)x=-x; 
    } 
    
    #define ll long long
    const int maxn=1e3+3;
    ll n,m,k,f[2][205][205][2],P=1000000007;
    char s1[maxn],s2[maxn];
    int main()
    {
        //freopen("b.in","r",stdin);
        rd(n),rd(m),rd(k);
        scanf("%s",s1+1);
        scanf("%s",s2+1);
        int now=1,pre=0;
        f[0][0][0][0]=f[1][0][0][0]=1;
        inc(i,1,n)
        {
            inc(j,1,m)
            inc(kk,1,k)
            {
                f[now][j][kk][0]=(f[pre][j][kk][0]+f[pre][j][kk][1])%P; 
                if(s1[i]==s2[j])
                {
                    f[now][j][kk][1]=(f[pre][j-1][kk][1]+f[pre][j-1][kk-1][0]+f[pre][j-1][kk-1][1])%P;
                }
                else f[now][j][kk][1]=0;
            }
            
            now^=pre^=now^=pre; 
        }
        
        printf("%lld",(f[n&1][m][k][0]+f[n&1][m][k][1])%P);
        re 0;
    }
    View Code

    T3 运输计划

    二分+树上差分

    #include<bits/stdc++.h>
    #define inc(i,l,r) for(int i=l;i<=r;++i)
    #define reg register
    #define re     return
    
    using namespace std;
    const int maxn=300005,maxm=600005;
    
    template<typename T>inline void rd(T&x)
    {
        char c;bool f=0;
        while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
        x=c^48;
        while((c=getchar())>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48);
        if(f)x=-x;
    }
    int n,m,k,k1,l,r,num,res,maxlen;
    int to[maxm],nt[maxm],to1[maxm],val[maxm],nt1[maxm],head1[maxm],dis[maxn],head[maxn],faa[maxn],vis[maxn],cnt[maxn],a[maxn];
    
    
    struct node
    {
        int x,y,lca,dis;
    }ask[maxn];
    
    inline void add(int x=0,int y=0,int z=0)
    {
        rd(x),rd(y),rd(z);
        to[++k]=y;nt[k]=head[x];val[k]=z;head[x]=k;
        to[++k]=x;nt[k]=head[y];val[k]=z;head[y]=k;
        r+=z;
    }
    
    inline void add1(int x,int y)
    {
        nt1[++k1]=head1[x];head1[x]=k1;to1[k1]=y;
        nt1[++k1]=head1[y];head1[y]=k1;to1[k1]=x;
    }
    //-----------------------------------------tarjan------------------------------------------------//
    inline int find(int x){re x==faa[x]?x:faa[x]=find(faa[x]);    }
    
    void tarjan(int u,int fa)
    {
        for(int i=head[u];i;i=nt[i])
        {
            int v=to[i],w=dis[u]+val[i];
            if(v==fa)continue;
            dis[v]=w;
            a[v]=w-dis[u];
            tarjan(v,u);
            int f1=find(v);
            int f2=find(u);
            if(f1!=f2)
                faa[f1]=find(f2);
            vis[v]=1;
        }
        
        for(int i=head1[u];i;i=nt1[i])
        {
            int v=to1[i];
            if(vis[v])
            {
                int now=(i+1)>>1;
                ask[now].lca=find(faa[v]);
                ask[now].dis=dis[v]+dis[u]-(dis[ask[now].lca]<<1);
                maxlen=max(ask[now].dis,maxlen);
            }
        }
    }
    //--------------------------------------------差分-----------------------------------------------//
    
    void dfvv(int u,int fa)
    {
        for(int i=head[u];i;i=nt[i])
        {
            int v=to[i];
            if(v!=fa)
            {
                dfvv(v,u);
                cnt[u]+=cnt[v];
            }
        }
        if(cnt[u]==num&&a[u]>res)res=a[u];    
    } 
    
     inline bool check(int x)
     {
         memset(cnt,0,sizeof(cnt));
         
         res=num=0;
         for(int i=1;i<=m;i++)
         if(ask[i].dis>x) cnt[ask[i].x]++,cnt[ask[i].y]++,cnt[ask[i].lca]-=2,num++;
        
        dfvv(1,0);
        
         re maxlen-res<=x;
     }
    //--------------------------------------------main-----------------------------------------------//
    int main()
    {    
        //freopen("testdata(2).in","r",stdin);
        //    freopen("in.txt","r",stdin);
        
        rd(n),rd(m);
        inc(i,2,n)add();
        inc(i,1,m){
            rd(ask[i].x),rd(ask[i].y);
            add1(ask[i].x,ask[i].y);
        }
        
        inc(i,1,n)faa[i]=i;
        tarjan(1,0);
        
        while(l<=r)
        {
            int mid=(l+r)>>1;
            if(check(mid))r=mid-1;
            else l=mid+1;
        }
        
        printf("%d",l);
        re 0;
    }
    View Code

    五.noip2014

    day 1

    T1 生活大爆炸版石头剪刀布

    zz 模拟

    直接模拟打表就好

    反正我看不出什么规律

    #include<bits/stdc++.h>
    #define re return
    #define sta static
    #define supervisor liangsiyi.mz
    #define inc(i,l,r) for(int i=l;i<=r;++i) 
    #define dec(i,l,r) for(int i=l;i>=r;--i)
    
    using namespace std;
    int n,cost[5][5]={0,0,1,1,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,1,1,1,0,0,0};
    int a[205],b[205];
    inline int read()
    {
        int date=0;char c=' ';
        while('0'>c||c>'9')c=getchar();
        while('0'<=c&&c<='9'){date=(date<<3)+(date<<1)+(c^48);c=getchar();}
        re date;
    }
    
    void dfs()
    {
        
        
    }
    
    int main()
    {
        int x,y,sa=0,sb=0;;
        scanf("%d%d%d",&n,&x,&y);
        inc(i,1,x)
        scanf("%d",&a[i]);
        inc(i,1,y)
        scanf("%d",&b[i]);
        
        int i=0,j=0;
        inc(k,1,n)
        {
            i=(i+1)>x?1:i+1;
            j=(j+1)>y?1:j+1;
            sa+=cost[a[i]][b[j]];
            sb+=cost[b[j]][a[i]];
        }
        
        printf("%d %d",sa,sb);
    }
    View Code

    T2 联合权值

    #include<bits/stdc++.h>
    #define re return
    #define inc(i,l,r) for(int i=l;i<=r;++i)
    using namespace std;
    template<typename T>inline void rd(T&x)
    {
        char c;bool f=0;
        while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
        x=c^48;
        while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
        if(f)x=-x;
    }
    
    typedef long long ll;
    const int maxn=2e5+5;
    ll n,m,w[maxn],P=10007,hd[maxn];
    struct node{
        int to,nt;
    }e[maxn<<1];
    int k;
    inline void add(int x,int y)
    {
        e[++k]=(node){y,hd[x]};hd[x]=k;
    }
    
    ll ans=0,mmm;
    inline void dfs(int x,int fa)
    {
        ll sum=0,maxx=w[fa];
        for(int i=hd[x];i;i=e[i].nt)
        {
            int v=e[i].to;
            if(v==fa)continue;
            dfs(v,x);
            ans=(ans+(w[fa]+sum)*w[v])%P;
            mmm=max(mmm,w[v]*maxx);
            maxx=max(maxx,w[v]);
            sum=(sum+w[v])%P;
        }
    }
    
    int main()
    {
        freopen("a.in","r",stdin);
        int x,y;
        rd(n);
        inc(i,2,n)
        {
            rd(x),rd(y);
            add(x,y);
            add(y,x);
        }
        
        inc(i,1,n)rd(w[i]);
        dfs(1,0);
        printf("%lld %lld",mmm,ans*2ll%P);
        re 0;
    }
    View Code

    T3 飞扬的小鸟

    背包

    #include<bits/stdc++.h>
    #define re return
    #define sta static
    #define supervisor liangsiyi.mz
    #define ll long long
    #define inc(i,l,r) for(int i=l;i<=r;++i) 
    #define dec(i,l,r) for(int i=l;i>=r;--i)
    #define M 0x3f3f3f3f
    
    using namespace std;
    int n,m,k,e[10005],xx[10005],yy[10005],l[10005],h[10005],f[10005][2005],x,y,z,ans; 
    inline int read()
    {
        int date=0;char c=' ';
        while('0'>c||c>'9')c=getchar();
        while('0'<=c&&c<='9'){date=(date<<3)+(date<<1)+(c^48);c=getchar();}
        re date;
    }
    
    
    
    int main()
    {
    //    freopen("testdata1.in","r",stdin);
        
        n=read(),m=read(),k=read();
        inc(i,1,n)h[i]=m,l[i]=1;
        inc(i,1,n)xx[i]=read(),yy[i]=read();
        inc(i,1,k)
        {x=read();y=read();z=read();
        e[x]=1;l[x]=y+1;h[x]=z-1;}
        
        memset(f,0x3f3f3f3f,sizeof(f));
        inc(i,1,m)f[0][i]=0;
        inc(i,1,n)
        {
            
            inc(j,xx[i]+1,m+xx[i])                                                    //浠?1  寮€  濮?锛?鍚?鍒?浼?閬?婕?
                f[i][j]=min(f[i-1][j-xx[i]]+1,f[i][j-xx[i]]+1);
            inc(j,m+1,m+xx[i])
                f[i][m]=min(f[i][m],f[i][j]);
            inc(j,1,m-yy[i])
                f[i][j]=min(f[i][j],f[i-1][j+yy[i]]);
            inc(j,1,l[i]-1)
                f[i][j]=M;
            inc(j,h[i]+1,m)
                f[i][j]=M;
        }    
        
            int sum=0x3f3f3f3f;
            inc(i,1,m)
            if(f[n][i])sum=min(sum,f[n][i]);
            
            if(sum!=0x3f3f3f3f)printf("1
    %d",sum);
            else 
            {
                dec(i,n,1)
                {    y=0;
                    inc(j,1,m)
                    if(f[i][j]<M)
                    {
                        inc(k,1,i)
                        if(e[k])ans++;
                        printf("0
    %d",ans);
                        re 0;
                    }            
                }    
            }
        re 0;
    }
    View Code

    day 2

    T1 无线网络发射器选址

    二维前缀和

    #include<bits/stdc++.h>
    #define re return
    #define inc(i,l,r) for(int i=l;i<=r;++i)
    template<typename T>inline void rd(T&x)
    {
        char c;bool f=0;
        while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
        x=c^48;
        while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
        if(f)x=-x;
    }
    using namespace std;
    int n,m,d,a[150][150],ans,cnt;
    int main()
    {
        rd(d);
        rd(n);
        int k,x,y,l,r;
        inc(i,1,n)
        {
            rd(x),rd(y);
            rd(k);
            a[x+1][y+1]=k;
        }
        
        inc(i,1,129)inc(j,1,129)
        a[i][j]+=a[i-1][j]+a[i][j-1]-a[i-1][j-1];
        
        inc(i,1,129)inc(j,1,129)
        {
            l=i-d-1<0?0:i-d-1;
            r=i+d>129?129:i+d;
            x=j-d-1<0?0:j-d-1;
            y=j+d>129?129:j+d;
            k=a[y][r]-a[y][l]-a[x][r]+a[x][l];
            if(k>ans)ans=k,cnt=1;
            else if(ans==k)
            ++cnt;
        }
        
        printf("%d %d",cnt,ans);
        re 0;
    }
    View Code

    貌似写法有点奇怪

    T2 寻找道路

    #include<bits/stdc++.h>
    #define re return
    #define inc(i,l,r) for(int i=l;i<=r;++i)
    using namespace std;
    template<typename T>inline void rd(T&x)
    {
        char c;bool f=0;
        while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
        x=c^48;
        while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
        if(f)x=-x;
    }
    
    const int maxn=1e4+5,maxm=2e5+5;
    int n,m,hd[maxn],vis[maxn],ok[maxn];
    struct node{
        int to,nt;
    }e[maxm<<1];
    int k;
    inline void add(int x,int y){
        e[++k]=(node){y,hd[x]};hd[x]=k;
    }
    
    inline void dfs(int x)
    {
        vis[x]=ok[x]=1;
        for(int i=hd[x];i;i=e[i].nt)
        {
            int v=e[i].to;
            if(!vis[v])dfs(v);
        }
    }
    
    int dis[maxn],inf=5e5;
    struct nide{
        int x,val;
        inline bool operator<(nide b)const {
            re val>b.val;
        }
    };
    int s,t;
    inline void dij()
    {
        inc(i,1,n)dis[i]=inf;
        priority_queue<nide>q;
        dis[t]=0;
        q.push((nide){t,0});
        while(!q.empty())
        {
            nide u=q.top();
            q.pop();
            int x=u.x;
            if(dis[x]!=u.val)continue;
            for(int i=hd[x];i;i=e[i].nt)
            {
                int v=e[i].to;
                if(ok[v]&&dis[v]>dis[x]+1)
                {
                    dis[v]=dis[x]+1;
                    q.push((nide){v,dis[v]});
                }
            }
        }
        if(dis[s]==inf)printf("-1");
        else printf("%d",dis[s]);
    }
    int main()
    {
        freopen("a.in","r",stdin);
        rd(n),rd(m);
        int x,y;
        inc(i,1,m)
        {
            rd(x),rd(y);
            add(y,x);
        }
        rd(s),rd(t);
        dfs(t);
        vis[s]=1;
        inc(i,1,n)
        if(!vis[i])
        {
            for(int j=hd[i];j;j=e[j].nt)
            {
                int v=e[j].to;
                ok[v]=0;
            }
        }
        dij();
    }
    View Code

    T3 解方程

    多取几遍mod就好

    #include<bits/stdc++.h>
    #define re return
    #define inc(i,l,r) for(int i=l;i<=r;++i)
    using namespace std;
    template<typename T>inline void rd(T&x)
    {
        char c;bool f=0;
        while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
        x=c^48;
        while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
        if(f)x=-x; 
    }
    
    #define ll long long
    
    ll mod[4]={47809,47807,102931,102929};
    ll a[105][4],n,m;
    char s[10005];
    
    int cnt,ans[1000005];
    bool vis[1000005];
    
    inline bool check(int x)
    {
    
        for(int i=0;i<4;++i)
        {
            ll tmp=a[n][i];
            for(int j=n-1;j>=0;--j)
                tmp=(tmp*x+a[j][i])%mod[i];
            
            if(tmp)
            {
                for(int j=x;j<=m;j+=mod[i])
                vis[j]=1;
                re 0;
            }
        }
        re 1;
    }
    
    int main()
    {
        int len;
        rd(n),rd(m);
        inc(i,0,n)
        {
            scanf("%s",s+1);
            len=strlen(s+1);
            inc(k,0,3)
            {
                ll tmp=0,flag=1; 
                inc(j,1,len)
                if(s[j]=='-')flag=-1;
                    else tmp=(tmp*10+(s[j]^48))%mod[k];
                a[i][k]=tmp*flag;
            } 
        }
        
        inc(i,1,m)
        if(!vis[i]&&check(i))ans[++cnt]=i;
        
        printf("%d
    ",cnt);
        inc(i,1,cnt)
        printf("%d
    ",ans[i]);
        re 0;
    }
    View Code
  • 相关阅读:
    华为平板暴力禁用wifi
    传输层与数据层架构一二谈
    内外网访问控制设计
    机房通信网设计
    list add元素覆盖之前元素问题思考
    IIS8无法调用Oracle.DataAccess .dll问题
    线程令牌
    Socket解决粘包问题2
    Socket解决粘包问题1
    Socket异步通信学习三
  • 原文地址:https://www.cnblogs.com/lsyyy/p/11845426.html
Copyright © 2011-2022 走看看