Day3 题解

传送门 密码:xjzjd (相聚在京东 吉大交大)

T1:

思路:单调栈

让刚刚进入单调栈的那个东西来干掉他们之前的东西

稍微改一下如何判定单调就可轻松AC

给出代码:

#include<bits/stdc++.h>
using namespace std;
#define gg c=getchar()
#define pd (c>='0'&&c<='9')
void wr(int n)
{
    if(n<0)return;
    if(n>9)wr(n/10);
    putchar(n%10+48);
}
inline void write(int n)
{
    if(n<0)
    {
        putchar('-');
        n=-n;
    }
    wr(n);
    putchar('\n');
}
inline int read()
{
    int s=0,t=1;
    char gg;
    for(;!pd;gg)if(c=='-')t=-1;
    for(;pd;gg)s=(s<<1)+(s<<3)+c-'0';
    return s*t;
}
int now;
struct poi
{
    int id,sum;
}sta[100100];
int a[2001001];
inline void push(int sum,int id)
{
    sta[++now].id=id;
    sta[now].sum=sum;
}
inline void add(int n)
{
    sta[now].sum+=n;
}
int main()
{
    int n=read();
    int cnt=n;
    push(1,-10100000);
    for(int i=1;i<=n;i++)
    {
        a[i+n]=a[i]=read();
        push(a[i],i);
        while(sta[now].sum<0&&(i-sta[now].id)<=n)
        {
            int num=sta[now].sum;
            now--;
            add(num);
            cnt--;
        }
    }
    for(int i=1+n;i<=n+n;i++)
    {
        push(a[i],i);
        while(sta[now].sum<0&&i-sta[now].id<=n)
        {
            if(sta[now].id<=n)cnt--;
            int num=sta[now].sum;
            now--;
            add(num);
        }
    }
    write(cnt);
}

T2

一个简单的二维偏序贪心

与传送门内的这道题完全一样

当年wxg讲过,没改题的或者是改完提忘了的扇自己两个大嘴巴子我带头

代码不给了,不会的活该

真香

#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct boli
{
    ll time,rp;
}g[200100];
inline bool cmp(const boli haitai,const boli cui)
{
    return haitai.time<cui.time;
}
ll n,ans;
priority_queue<ll,vector<ll>,greater<ll> >q;
int main()
{
    scanf("%lld",&n);
    for(int i=1;i<=n;i++)scanf("%lld%lld",&g[i].time,&g[i].rp);
    sort(g+1,g+n+1,cmp);
    int now;
    q.push(1<<30);
    for(int i=1;i<=n;i++)
    {
        if(g[i].time<1||g[i].rp<0)
        {
            g[i].rp=1<<30;
            continue;
        }
        now=g[i].time;
        ans+=g[i].rp;
        q.push(g[i].rp);
        if(q.size()>now+1)
        {
            ans-=q.top();
            q.pop();
        }
    }
    printf("%lld",ans);
}

T3

树链剖分裸题

直接给代码

#include<bits/stdc++.h>
using namespace std;
#define ls k<<1
#define rs k<<1|1
#define gg c=getchar()
#define pd (c>='0'&&c<='9')
inline int read()
{
    int s=0;
    bool t=1;
    char gg;
    for(;!pd;gg)if(c=='-')s=-1;
    for(;pd;gg)s=(s<<1)+(s<<3)+c-'0';
    return s*t;
}
struct edge
{
    int to,nxxt,len;
}e[500100<<1];
int head[500100],cnt;
inline void addedge(int u,int v,int w)
{
    cnt++;
    e[cnt].len=w;
    e[cnt].to=v;
    e[cnt].nxxt=head[u];
    head[u]=cnt;
}
int fa[500100],son[500100],size[500100],deep[500100];
void dfs1(int u,int f)
{
    fa[u]=f;
    size[u]=1;
    deep[u]=deep[f]+1;
    for(int i=head[u];~i;i=e[i].nxxt)
    {
        int to=e[i].to;
        if(to==f)continue;
        dfs1(to,u);
        size[u]+=size[to];
        if(size[to]>size[son[u]])son[u]=to;
    }
}
int rev[500100],seg[500100],top[500100],tcnt;
bool vis[500100];
void dfs2(int u,int f)
{
    vis[u]=1;
    seg[u]=++tcnt;
    top[u]=f;
    rev[tcnt]=u;
    if(son[u])dfs2(son[u],f);
    for(int i=head[u];~i;i=e[i].nxxt)
    {
        int to=e[i].to;
        if(!vis[to])dfs2(to,to);
    }
}
/***************************************************///线段树 
struct tree
{
    int le,ri,lz,sum; 
}t[500100<<2];
inline void pushup(int k)
{
    t[k].sum=t[ls].sum+t[rs].sum;
}
inline void pushdown(int k)
{
    if(!~t[k].lz)return ;
    t[ls].lz=t[k].lz,t[rs].lz=t[k].lz;
    t[ls].sum=t[k].lz*(t[ls].ri-t[ls].le+1);
    t[rs].sum=t[k].lz*(t[rs].ri-t[rs].le+1);
    t[k].lz=-1;
}
void build(int k,int l,int r)
{
    t[k].le=l;t[k].ri=r;t[k].lz=-1;
    if(l==r)return ;
    int mid=(l+r)>>1;
    build(ls,l,mid);build(rs,mid+1,r);
}
void modify(int k,int l,int r,int v)
{
    int le=t[k].le,ri=t[k].ri;
    if(l==le&&r==ri)
    {
        t[k].sum=v*(ri-le+1);
         
        t[k].lz=v;
        return;
    }
    pushdown(k);
    int mid=(le+ri)>>1;
    if(l>mid)modify(rs,l,r,v);
    else if(mid+1>r)modify(ls,l,r,v);
    else modify(ls,l,mid,v),modify(rs,mid+1,r,v);
    pushup(k);
}
int query(int k,int n)
{
    int le=t[k].le,ri=t[k].ri;
    if(le==n&&ri==n)
    {
        return t[k].sum;
    }
    pushdown(k);
    int mid=(le+ri)>>1;
    if(n>mid)return query(rs,n);
    else return query(ls,n);
}
/***************************************************///线段树 
inline void add(int u)
{
    modify(1,seg[u],seg[u]+size[u]-1,1);
}
void out(int u)
{
    if(top[u]!=1)out(fa[top[u]]);
    modify(1,seg[top[u]],seg[u],0);
}
void ask(int u)
{
    printf("%d\n",query(1,seg[u]));
}
int main()
{
    //freopen("test3.in","r",stdin);
     
    memset(head,-1,sizeof head);
    int n=read();
    for(int i=1;i<n;i++)
    {
        int u=read(),v=read();
        addedge(u,v,1);
        addedge(v,u,1);
    }
    dfs1(1,0);dfs2(1,1);build(1,1,n);
    int m=read();
    for(int i=1;i<=m;i++)
    {
        int o=read();
        int n=read();
        if(o==1)add(n);
        else if(o==2)out(n);
        else ask(n);
    }
}

猜你喜欢

转载自www.cnblogs.com/yanghaokun/p/10133906.html