看似很努力的刷题

pj还没1=的我又开始颓废了。。。

今天胡写了四道题,感觉Dev和Luogu-IDE都在坑我。。。

1.Luogu P4001 [BJOI2006]狼抓兔子

链接:https://www.luogu.org/problemnew/show/P4001

挺水的,就是先跑Dinic+剪枝,再用最大流最小割定理求出答案

#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#define maxn 500100
#define inf 0x7fffffff
#define mt(x,y) memset(x,y,sizeof(x))
#define max(x,y) x>y?x:y
#define min(x,y) x<y?x:y
#define abs(x) x>0?x:-x
inline void read(int &x)
{
    x=0;int f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-f;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    x*=f;
}
using namespace std;
#define N 1000001
#define M 6000001
int n,m,h[N],q[N],head[N],cnt=1;
struct edge{
    int to,next,v;
}e[M];
void add(int u,int v,int w)
{
    e[++cnt].to=v;
    e[cnt].next=head[u];
    e[cnt].v=w;
    head[u]=cnt;
}
bool bfs()
{
    int l=0,r=1,now;
    q[0]=1;
    mt(h,-1);
    h[1]=0;
    while(l<r)
    {
        now=q[l++];
        for(register int i=head[now];i;i=e[i].next)
            if(e[i].v&&h[e[i].to]<0)
            {
                h[e[i].to]=h[now]+1;
                q[r++]=e[i].to;
            }
    }
    if(h[n*m]==-1)return 0;
    else return 1;
}
int dfs(int x,int f)
{
    if(n*m==x)
        return f;
    int used=0,w;
    for(register int i=head[x];i;i=e[i].next)
        if(e[i].v&&h[x]+1==h[e[i].to])
        {
            w=dfs(e[i].to,min(f-used,e[i].v));
            e[i].v-=w;
            e[i^1].v+=w;
            used+=w;
            if(used==f)
                return f;
        }
    if(!used)
        h[x]=-1;
    return used;
}
int ans=0;
int dinic(){
    while(bfs())
        while(1)
        {
            int tmp=dfs(1,inf);
            if(!tmp)
                break;
            ans+=tmp;
        }
    return ans;
}
int main(){
    read(n);read(m);
    int x;
    for(register int i=1;i<=n;++i)
        for(register int j=1;j<m;++j)
        {
            read(x);
            add(m*(i-1)+j,m*(i-1)+j+1,x);
            add(m*(i-1)+j+1,m*(i-1)+j,x);
        }
    for(register int i=1;i<n;++i)
        for(register int j=1;j<=m;++j)
        {
            read(x);
            add(m*(i-1)+j,m*(i)+j,x);
            add(m*(i)+j,m*(i-1)+j,x);
        }
    for(register int i=1;i<n;++i)
        for(register int j=1;j<m;++j)
        {
            read(x);
            add(m*(i-1)+j,m*(i)+j+1,x);
            add(m*(i)+j+1,m*(i-1)+j,x);
        }
    dinic();
    printf("%d\n",ans);
    return 0;
}

2.Luogu P3369 【模板】普通平衡树

链接:https://www.luogu.org/problemnew/show/P3369

打个Splay就过了。。。

#pragma GCC optimize("O3")
#include <bits/stdc++.h>
using namespace std;
#define Max 500100
int root=0,N,tot=0;
inline int read()
{
    register int x=0,t=1;register char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    if(ch=='-') t=-1,ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-48,ch=getchar();
    return x*t;
}
struct node{
    int ch[2],ff,son;
    int cnt,val;
}t[Max];
inline void push_up(int x)
{
    t[x].son=t[t[x].ch[0]].son+t[t[x].ch[1]].son+t[x].cnt;
}
void rotate(int x)
{
    register int y=t[x].ff;
    register int z=t[y].ff;
    register int k=t[y].ch[1]==x;
    t[z].ch[t[z].ch[1]==y]=x;
    t[x].ff=z;
    t[y].ch[k]=t[x].ch[k^1];
    t[t[x].ch[k^1]].ff=y;
    t[x].ch[k^1]=y;
    t[y].ff=x;
    push_up(y);
    push_up(x);
}
inline void Splay(int x,int goal)
{
    while(t[x].ff!=goal)
    {
        int y=t[x].ff;
        int z=t[y].ff;
        if(z!=goal)
            (t[y].ch[0]==x)^(t[z].ch[0]==y)?rotate(x):rotate(y);
        rotate(x);
    }
    if(goal==0)
        root=x;
}
inline void insert(int x)
{
    int u=root,ff=0;
    while(u&&t[u].val!=x)
    {
        ff=u;
        u=t[u].ch[x>t[u].val];
    }
    if(u)
        ++t[u].cnt;
    else
    {
        u=++tot;
        if(ff)
            t[ff].ch[x>t[ff].val]=u;
        t[tot].ch[0]=0;
        t[tot].ch[1]=0;
        t[tot].ff=ff;
        t[tot].val=x;
        t[tot].cnt=1;
        t[tot].son=1;
    }
    Splay(u,0);
}
inline void Find(int x)
{
    int u=root;
    if(!u)
        return;
    while(t[u].ch[x>t[u].val]&&x!=t[u].val)
        u=t[u].ch[x>t[u].val];
    Splay(u,0);
}
inline int Next(int x,int f)
{
    Find(x);
    int u=root;
    if((t[u].val>x&&f)||(t[u].val<x&&!f))
        return u;
    u=t[u].ch[f];
    while(t[u].ch[f^1])
        u=t[u].ch[f^1];
    return u;
}
inline void Delete(int x)
{
    int last=Next(x,0),next=Next(x,1);
    Splay(last,0);
    Splay(next,last);
    int del=t[next].ch[0];
    if(t[del].cnt>1)
    {
        --t[del].cnt;
        Splay(del,0);
    }
    else
        t[next].ch[0]=0;
}
inline int K_th(int x)
{
    int u=root;
    if(t[u].son<x)
        return false;
    while(19260817)
    {
        int y=t[u].ch[0];
        if(x>t[y].son+t[u].cnt)
        {
            x-=t[y].son+t[u].cnt;
            u=t[u].ch[1];
        }
        else if(t[y].son>=x)
            u=y;
        else
            return t[u].val;
    }
}
int main()
{
    insert(-2147483647);
    insert(+2147483647);
    N=read();
    while(N--)
    {
        int opt=read(),x=read();
        switch(opt)
        {
            case 1:
                insert(x);
                break;
            case 2:
                Delete(x);
                break;
            case 3:
                Find(x);
                printf("%d\n",t[t[root].ch[0]].son);
                break;
            case 4:
                printf("%d\n",K_th(x+1));
                break;
            case 5:
                printf("%d\n",t[Next(x,0)].val);
                break;
            case 6:
                printf("%d\n",t[Next(x,1)].val);
                break;
        }
    }
    return 0;
}

3.Luogu P2590 [ZJOI2008]树的统计

链接:https://www.luogu.org/problemnew/show/P2590

树剖模板,15分钟码完,调了1个小时才发现querymax判定不再区间内时写了return 0(Orz)

#pragma GCC optimize("O3")
#include <bits/stdc++.h>
using namespace std;
inline int read() 
{
    int x=0,f=1;char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    for(;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*f;
}
struct node{
    int to,next;
}e[60100];
int head[30005],num=0;
inline void add(int s,int t)
{
    e[++num].to=t;
    e[num].next=head[s];
    head[s]=num;
}
int dep[300005],a[30005],ch[30005],top[30005];
int fa[30005],son[30005],l[30005],size[30005];
int sum[240005],vmax[240005];
int n,m,tot=0;
inline void pushup(int x)
{
    sum[x]=sum[x<<1]+sum[x<<1|1];
    vmax[x]=max(vmax[x<<1],vmax[x<<1|1]);
}
inline void build(int x,int l,int r)
{
    if(l==r)
    {
        sum[x]=a[l];
        vmax[x]=a[l];
        return;
    }
    int mid=(l+r)>>1;
    build(x<<1,l,mid);
    build(x<<1|1,mid+1,r);
    pushup(x);
}
inline void update(int x,int l,int r,int pos,int v)
{
    if(l==r)
    {
        sum[x]=v;
        vmax[x]=v;
        return;
    }
    int mid=(l+r)>>1;
    if(pos<=mid)
        update(x<<1,l,mid,pos,v);
    else
        update(x<<1|1,mid+1,r,pos,v);
    pushup(x);
}
inline int querymax(int x,int l,int r,int L,int R)
{
    if(R<l||r<L)
        return -2147483647;
    if(L<=l&&r<=R)
        return vmax[x];
    int mid=(l+r)>>1;
    return max(querymax(x<<1,l,mid,L,R),querymax(x<<1|1,mid+1,r,L,R));
}
inline int cal1(int x,int y)
{
    int ans=-2147483647;
    int fx=top[x],fy=top[y];
    while(fx!=fy)
    {
        if(dep[fx]<dep[fy])
            swap(x,y),swap(fx,fy);
        ans=max(ans,querymax(1,1,tot,l[fx],l[x]));
        x=fa[fx];
        fx=top[x];
    }
    if(l[x]>l[y])
        swap(x,y);
    ans=max(ans,querymax(1,1,tot,l[x],l[y]));
    return ans;
}
inline int querysum(int x,int l,int r,int L,int R)
{
    if(R<l||r<L)
        return 0;
    if(L<=l&&r<=R)
        return sum[x];
    int mid=(l+r)>>1;
    return querysum(x<<1,l,mid,L,R)+querysum(x<<1|1,mid+1,r,L,R);
}
inline int cal2(int x,int y)
{
    int ans=0;
    int fx=top[x],fy=top[y];
    while(fx!=fy)
    {
        if(dep[fx]<dep[fy])
            swap(x,y),swap(fx,fy);
        ans+=querysum(1,1,tot,l[fx],l[x]);
        x=fa[fx];
        fx=top[x];
    }
    if(l[x]>l[y])
        swap(x,y);
    ans+=querysum(1,1,tot,l[x],l[y]);
    return ans;
}
inline void dfs1(int x)
{
    size[x]=1;
    for(register int i=head[x];i;i=e[i].next)
    {
        int v=e[i].to;
        if(!dep[v])
        {
            dep[v]=dep[x]+1;
            fa[v]=x;
            dfs1(v);
            size[x]+=size[v];
            if(size[son[x]]<size[v])
                son[x]=v;
        }
    }
}
inline void dfs2(int x,int t)
{
    l[x]=++tot;
    a[tot]=ch[x];
    top[x]=t;
    if(son[x])
        dfs2(son[x],t);
    for(register int i=head[x];i;i=e[i].next)
    {
        int v=e[i].to;
        if(v!=fa[x]&&v!=son[x])
            dfs2(v,v);
    }
}
int main()
{
    memset(head,0,sizeof(head));
    n=read();
    for(register int i=1;i<n;++i)
    {
        int x=read(),y=read();
        add(x,y);
        add(y,x);
    }
    for(register int i=1;i<=n;++i)
        ch[i]=read();
    dep[1]=1;
    fa[1]=1;
    dfs1(1);
    dfs2(1,1);
    build(1,1,n);
    m=read();
    while(m--)
    {
        string str;int x,y;
        cin>>str;
        scanf("%d%d",&x,&y);
        if(str=="CHANGE")
            update(1,1,n,l[x],y);
        else if(str=="QMAX")
            printf("%d\n",cal1(x,y));
        else
            printf("%d\n",cal2(x,y));
    }
    return 0;
}

4.Luogu P3391 【模板】文艺平衡树(Splay)

扫描二维码关注公众号,回复: 2803365 查看本文章

链接:https://www.luogu.org/problemnew/show/P3391

还是Splay模板,这好像是我打过最短的Splay(绝不压行)

#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#define N 100005
using namespace std;
int n,m;
int fa[N],ch[N][2],size[N],rev[N],rt;
inline void pushup(int x)
{
    size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
}
inline void build(int l,int r,int f)
{
    if(l>r)
        return;
    int mid=(l+r)>>1;
    if(mid<f)
        ch[f][0]=mid;
    else
        ch[f][1]=mid;
    fa[mid]=f;
    size[mid]=1;
    if(l==r)
        return;
    build(l,mid-1,mid);
    build(mid+1,r,mid);
    pushup(mid);
}
inline void rotate(int x,int &k)
{
    int y=fa[x],z=fa[y],kind=ch[y][0]==x;
    if(y==k)
        k=x;
    else
        ch[z][ch[z][0]!=y]=x;
    ch[y][kind^1]=ch[x][kind];
    fa[ch[y][kind^1]]=y;
    ch[x][kind]=y;
    fa[y]=x;
    fa[x]=z;
    pushup(x);
    pushup(y);
}
inline void Splay(int x,int &k)
{
    while(x!=k)
    {
        int y=fa[x],z=fa[y];
        if(y!=k)
            (ch[y][0]==x)^(ch[z][0]==y)?rotate(x,k):rotate(y,k);
        rotate(x,k);
    }
}
inline void pushdown(int x)
{
    if(rev[x])
    {
        swap(ch[x][0],ch[x][1]);
        rev[ch[x][0]]^=1;
        rev[ch[x][1]]^=1;
        rev[x]=0;
    }
}
inline int find(int x,int k)
{
    pushdown(x);
    int s=size[ch[x][0]];
    if(k==s+1)
        return x;
    else if(k<=s)
        return find(ch[x][0],k);
    else
        return find(ch[x][1],k-s-1);
}
inline void reverse(int l,int r)
{
    int x=find(rt,l),y=find(rt,r+2);
    Splay(x,rt);
    Splay(y,ch[x][1]);
    int z=ch[y][0];
    rev[z]^=1;
}
int main()
{
    scanf("%d%d",&n,&m);
    rt=(n+3)/2;
    build(1,n+2,rt);
    while(m--)
    {
        int l,r;
        scanf("%d%d",&l,&r);
        reverse(l,r);
    }
    for(register int i=2;i<=n+1;++i)
        printf("%d ",find(rt,i)-1);
    return 0;
}

我好颓废啊!

猜你喜欢

转载自www.cnblogs.com/yzhang-rp-inf/p/9490592.html