看似很努力的刷题【2】(长者生日祭)

Happy Birthday 长者!

我还是很颓废啊

1.Luogu P3373 【模板】线段树 2

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

我太弱了,这题都写,线段树无解释。。。

#pragma GCC optimize("O3")
#include <iostream>
#include <cstdio>
using namespace std;
int p;
long long a[100007];
struct node{
    long long v, mul, add;
}st[400007];
void bt(int root, int l, int r){
    st[root].mul=1;
    st[root].add=0;
    if(l==r)
        st[root].v=a[l];
    else{
        int m=(l+r)/2;
        bt(root*2, l, m);
        bt(root*2+1, m+1, r);
        st[root].v=st[root*2].v+st[root*2+1].v;
    }
    st[root].v%=p;
}
void pushdown(int root, int l, int r){
    int m=(l+r)/2;
    st[root*2].v=(st[root*2].v*st[root].mul+st[root].add*(m-l+1))%p;
    st[root*2+1].v=(st[root*2+1].v*st[root].mul+st[root].add*(r-m))%p;
    st[root*2].mul=(st[root*2].mul*st[root].mul)%p;
    st[root*2+1].mul=(st[root*2+1].mul*st[root].mul)%p;
    st[root*2].add=(st[root*2].add*st[root].mul+st[root].add)%p;
    st[root*2+1].add=(st[root*2+1].add*st[root].mul+st[root].add)%p;
    st[root].mul=1;
    st[root].add=0;
}
void ud1(int root, int stdl, int stdr, int l, int r, long long k){
    if(r<stdl || stdr<l)
        return ;
    if(l<=stdl && stdr<=r){
        st[root].v=(st[root].v*k)%p;
        st[root].mul=(st[root].mul*k)%p;
        st[root].add=(st[root].add*k)%p;
        return ;
    }
    pushdown(root, stdl, stdr);
    int m=(stdl+stdr)/2;
    ud1(root*2, stdl, m, l, r, k);
    ud1(root*2+1, m+1, stdr, l, r, k);
    st[root].v=(st[root*2].v+st[root*2+1].v)%p;
}
void ud2(int root, int stdl, int stdr, int l, int r, long long k){
    if(r<stdl || stdr<l)
        return ;
    if(l<=stdl && stdr<=r){
        st[root].add=(st[root].add+k)%p;
        st[root].v=(st[root].v+k*(stdr-stdl+1))%p;
        return ;
    }
    pushdown(root, stdl, stdr);
    int m=(stdl+stdr)/2;
    ud2(root*2, stdl, m, l, r, k);
    ud2(root*2+1, m+1, stdr, l, r, k);
    st[root].v=(st[root*2].v+st[root*2+1].v)%p;
}
long long query(int root, int stdl, int stdr, int l, int r){
    if(r<stdl || stdr<l)
        return 0;
    if(l<=stdl && stdr<=r)
        return st[root].v;
    pushdown(root, stdl, stdr);
    int m=(stdl+stdr)/2;
    return (query(root*2, stdl, m, l, r)+query(root*2+1, m+1, stdr, l, r))%p;
}
int main(){
    int n, m;
    scanf("%d%d%d", &n, &m, &p);
    for(int i=1; i<=n; i++)
        scanf("%lld", &a[i]);
    bt(1, 1, n);
    while(m--){
        int chk;
        scanf("%d", &chk);
        int x, y;
        long long k;
        if(chk==1){
            scanf("%d%d%lld", &x, &y, &k);
            ud1(1, 1, n, x, y, k);
        }
        else if(chk==2){
            scanf("%d%d%lld", &x, &y, &k);
            ud2(1, 1, n, x, y, k);
        }
        else{
            scanf("%d%d", &x, &y);
            printf("%lld\n", query(1, 1, n, x, y));
        }
    }
    return 0;
}

2.Luogu P2486 [SDOI2011]染色

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

树剖板题

#pragma GCCoptimize("O3")
#include<bits/stdc++.h>    
using namespace std;  
typedef long long ll;  
const int sigma_size=26;  
const int N=100+50;  
const int MAXN=100000+50;  
const int inf=0x3fffffff;  
const double eps=1e-8;  
const int mod=100000000+7;  
#define L(x) (x<<1)  
#define R(x) (x<<1|1)  
#define PII pair<int, int>  
#define mk(x,y) make_pair((x),(y))  
int n,m,edge_cnt,cnt,Lc,Rc;  
char str[N];  
int col[MAXN],head[MAXN],sz[MAXN],dep[MAXN],fa[MAXN],son[MAXN],top[MAXN],pos[MAXN];  
struct Edge{  
    int u,v,next;  
}edge[MAXN<<1];  
struct node{  
    int l,r;  
    int num,tag,lc,rc;  
}segtree[MAXN<<2];  
inline void init()
{  
    edge_cnt=cnt=0;  
    memset(head,-1,sizeof(head));  
}  
inline void addedge(int u,int v)
{  
    edge[edge_cnt].u=u; edge[edge_cnt].v=v;  
    edge[edge_cnt].next=head[u]; head[u]=edge_cnt++;  
}  
inline void dfs1(int u,int pre,int depth){  
    sz[u]=1; 
    fa[u]=pre; 
    son[u]=0; 
    dep[u]=depth;  
    for(register int i=head[u];i!=-1;i=edge[i].next)
    {  
        int v=edge[i].v;  
        if(v == pre)  
            continue;  
        dfs1(v,u,depth+1);  
        sz[u]+=sz[v];  
        if(sz[son[u]]<sz[v])  
            son[u]=v;  
    }  
}  
inline void dfs2(int u,int tp){  
    pos[u]=++cnt; 
    top[u]=tp;  
    if(son[u]!=0)  
        dfs2(son[u],top[u]);  
    for(register int i=head[u];i!=-1;i=edge[i].next)
    {  
        int v=edge[i].v;  
        if(v == fa[u] || v == son[u])  
            continue;  
        dfs2(v,v);  
    }  
}  
inline void push_down(int rt)
{  
    if(segtree[rt].tag)
    {  
        segtree[L(rt)].tag=segtree[R(rt)].tag=segtree[rt].tag;  
        segtree[L(rt)].num=segtree[R(rt)].num=1;  
        segtree[L(rt)].lc=segtree[L(rt)].rc=segtree[rt].lc;  
        segtree[R(rt)].lc=segtree[R(rt)].rc=segtree[rt].lc;  
        segtree[rt].tag=0;  
    }  
}  
inline void push_up(int rt)
{  
    segtree[rt].lc=segtree[L(rt)].lc; 
    segtree[rt].rc=segtree[R(rt)].rc;  
    int ans=segtree[L(rt)].num+segtree[R(rt)].num;  
    if(segtree[L(rt)].rc == segtree[R(rt)].lc)  
        ans--;  
    segtree[rt].num=ans;  
}  
inline void build(int rt,int l,int r)
{  
    segtree[rt].l=l; 
    segtree[rt].r=r; 
    segtree[rt].num=0;  
    if(l == r)  
        return ;  
    int mid=(l+r)>>1;  
    build(L(rt),l,mid); 
    build(R(rt),mid+1,r);  
}  
inline void update(int rt,int l,int r,int x){  
    if(segtree[rt].l == l && segtree[rt].r == r)
    {  
        segtree[rt].num=segtree[rt].tag=1;  
        segtree[rt].lc=segtree[rt].rc=x;  
        return ;  
    }  
    push_down(rt);  
    int mid=(segtree[rt].l+segtree[rt].r)>>1;  
    if(r<=mid)  
        update(L(rt),l,r,x);  
    else if(l>mid)  
        update(R(rt),l,r,x);  
    else 
    {  
        update(L(rt),l,mid,x); 
        update(R(rt),mid+1,r,x);  
    }  
    push_up(rt);  
}  
inline int query(int rt,int l,int r,int L,int R){  
    if(segtree[rt].l == L)  
        Lc=segtree[rt].lc;  
    if(segtree[rt].r == R)  
        Rc=segtree[rt].rc;  
    if(segtree[rt].l == l && segtree[rt].r == r)  
        return segtree[rt].num;  
    push_down(rt);  
    int mid=(segtree[rt].l+segtree[rt].r)>>1;  
    if(r<=mid)  
        return query(L(rt),l,r,L,R);  
    else if(l>mid)  
        return query(R(rt),l,r,L,R);  
    else
    {  
        int ans=query(L(rt),l,mid,L,R)+query(R(rt),mid+1,r,L,R);  
        if(segtree[L(rt)].rc == segtree[R(rt)].lc)  
            ans--;  
        return ans;  
    }  
    push_up(rt);  
}  
inline int solve(int u,int v,int id,int c){  
    int ans=0;  
    if(id == 1)
    {  
        while(top[u]!=top[v])
        {  
            if(dep[top[u]]<dep[top[v]])  
                swap(u,v);  
            update(1,pos[top[u]],pos[u],c);  
            u=fa[top[u]];  
        }  
        if(dep[u]>dep[v])  
            swap(u,v);  
        update(1,pos[u],pos[v],c);  
    }  
    else
    {   
        int ans1=-1,ans2=-1;   
        while(top[u]!=top[v])
        {  
            if(dep[top[u]]<dep[top[v]])
            {  
                swap(u,v); 
                swap(ans1,ans2);  
            }  
            ans+=query(1,pos[top[u]],pos[u],pos[top[u]],pos[u]);  
            if(Rc == ans1)  
                ans--;  
            ans1=Lc; u=fa[top[u]];  
        }  
        if(dep[u]<dep[v]){  
            swap(u,v); 
            swap(ans1,ans2);  
        }  
        ans+=query(1,pos[v],pos[u],pos[v],pos[u]);  
        if(Rc == ans1)  
            ans--;  
        if(Lc == ans2)  
            ans--;    
    }  
    return ans;  
}  
int main(){   
    scanf("%d%d",&n,&m);
    init();  
    for(register int i=1;i<=n;++i)  
        scanf("%d",&col[i]);  
    for(register int i=1;i<n;++i)
    {  
        int u,v;  
        scanf("%d%d",&u,&v);  
        addedge(u,v); 
        addedge(v,u);  
    }  
    dfs1(1,1,1); 
    dfs2(1,1); 
    build(1,1,n);  
    for(register int i=1;i<=n;++i)  
        update(1,pos[i],pos[i],col[i]);  
    while(m--)
    {  
        scanf("%s",str);  
        int u,v;  
        if(str[0] == 'C')
        {  
            int c;  
            scanf("%d%d%d",&u,&v,&c);  
            solve(u,v,1,c);  
        }  
        else
        { 
            int u,v;  
            scanf("%d%d",&u,&v);  
            printf("%d\n",solve(u,v,2,0));  
        }  
    }  
    return 0;  
}

3.Luogu P1486 [NOI2004]郁闷的出纳员

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

可以Splay,但我用了pb_ds的红黑数(逃~

#pragma GCC optimize("O3")
#include<cstdio>  
#include<iostream>  
#include<ext/pb_ds/assoc_container.hpp>  
#include<ext/pb_ds/tree_policy.hpp>  
using namespace __gnu_pbds;  
using namespace std;  
struct node{  
    int v,id;  
    node(int a,int b){v=a;id=b;}  
    bool operator >(node b) const  
    {return v==b.v?id>b.id:v>b.v;}  
};  
tree<node,null_type,greater<node>,rb_tree_tag,tree_order_statistics_node_update> T,TE;  
int main(){
    int n,m,k,s=0,q,ans=0;
    char c;
    scanf("%d%d",&n,&m);
    while(n--)
    {
        cin>>c;
        scanf("%d",&k);
        if(c=='I') 
        {
            k+=s;
            if(k>=m) 
                T.insert(node(k,n));
        }
        else if(c=='A') 
            m-=k,s-=k;
        else if(c=='S')
        {
            m+=k,s+=k;
            T.split(node(m,-1),TE);
            ans+=TE.size();
        }
        else    
            printf(k>T.size()?"-1\n":"%d\n",T.find_by_order(k-1)->v-s);
    }
    printf("%d\n",ans);
    return 0;
}

4.Luogu P3701 「伪模板」主席树

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

实际是巧妙的建图+最大流就行(膜蛤)

#pragma GCC optimize("O3")
#include<bits/stdc++.h>
#define re register
#define inf 500000000
#define s1 b1[i].id[0]
#define s2 b2[j].id[0] 
using namespace std;
struct pe
{
    int hp;
    string id;
};
pe b1[101],b2[101];
struct po
{
    int to,nxt,w;
}edge[300001];
int head[20001],cur[200001],num=-1,n,m,t,x,y,s,l,tot,sum,xu1,xu2,dep[20001];
inline int read()
{
    int x=0,c=1;
    char ch=' ';
    while((ch>'9'||ch<'0')&&ch!='-')ch=getchar();
    while(ch=='-')c*=-1,ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*c;
}
inline void add_edge(int from,int to,int w)
{
    edge[++num].nxt=head[from];
    edge[num].to=to;
    edge[num].w=w;
    head[from]=num;
}
inline void add(int from,int to ,int w)
{
    add_edge(from,to,w);
    add_edge(to,from,0);
}
inline bool bfs()
{
    memset(dep,0,sizeof(dep));
    queue<int> q;
    while(!q.empty())
    q.pop();
    dep[s]=1;
    q.push(s);
    while(!q.empty()){
        int u=q.front();
        q.pop();
        for(re int i=head[u];i!=-1;i=edge[i].nxt)
        {
            int v=edge[i].to;
            if(edge[i].w>0&&dep[v]==0)
            {
                dep[v]=dep[u]+1;
                if(v==t)
                return 1;
                q.push(v);
            }
        }
    }
    return 0;
}
inline int dfs(int u,int dis)
{
    if(u==t)
        return dis;
    int diss=0;
    for(re int& i=cur[u];i!=-1;i=edge[i].nxt)
    {
        int v=edge[i].to;
        if(edge[i].w!=0&&dep[v]==dep[u]+1)
        {
            int check=dfs(v,min(dis,edge[i].w));
            if(check)
            {
                diss+=check;
                dis-=check;
                edge[i].w-=check;
                edge[i^1].w+=check;
                if(dis==0) 
                    break;
            }
        }
    }
    return diss;
}
inline int dinic()
{
    int ans=0;
    while(bfs())
    {
        for(re int i=s;i<=t;++i)
            cur[i]=head[i];
        while(int d=dfs(s,inf))
            ans+=d;
    }
    return ans;
}
inline int pd1(int x)
{
    if(b1[x].id[0]=='J')
        return xu1; 
    else
        return 0;
}
inline int pd2(int x)
{
    if(b2[x].id[0]=='J')
        return xu2; 
    else
        return 0;
}
int main()
{
    memset(head,-1,sizeof(head));
    n=read();m=read();
    for(re int i=1;i<=n;++i)
        cin>>b1[i].id;
    for(re int i=1;i<=n;++i)
        cin>>b2[i].id;
    for(re int i=1;i<=n;++i)
        cin>>b1[i].hp;
    for(re int i=1;i<=n;++i)
        cin>>b2[i].hp;
    for(re int i=1;i<=n;++i)
    {
        if(b1[i].id[0]=='Y')
            xu1++;
        if(b2[i].id[0]=='Y')
            xu2++;
    }
    s=0;
    t=2*n+1;
    for(re int i=1;i<=n;++i)
        for(re int j=1;j<=n;++j)
        {
            if(s1=='J'&&(s2=='H'||s2=='W'))
                add(i,j+n,1);
            if(s1=='E'&&(s2=='J'||s2=='Y'))
                add(i,j+n,1);
            if(s1=='Y'&&(s2=='J'||s2=='H'))
                add(i,j+n,1);
            if(s1=='H'&&(s2=='E'||s2=='W'))
                add(i,j+n,1);
            if(s1=='W'&&(s2=='Y'||s2=='E'))
                add(i,j+n,1);
        }
    for(re int i=1;i<=n;++i)
        add(s,i,b1[i].hp+pd1(i)),add(i+n,t,b2[i].hp+pd2(i));
    cout<<min(dinic(),m);
}

5.Luogu P3258 [JLOI2014]松鼠的新家

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

树剖板题

#pragma GCC optimize("O3")
#include <bits/stdc++.h>
using namespace std;
struct node{
    int to,next;
}e[600005];
int head[300005],num=0;
inline void add(int x,int y)
{
    e[++num].to=y;
    e[num].next=head[x];
    head[x]=num;
}
int n,route[300005];
int son[300005],fa[300005],size[300005],l[300005],top[300005],dep[300005],tot=0;
int sum[1200005],tag[1200005];
int cnt=1,pos[300005];
inline void update(int x,int l,int r,int L,int R,int v)
{
    if(R<l||r<L)
        return;
    if(L<=l&&r<=R)
    {
        sum[x]+=(r-l+1)*v;
        tag[x]+=v;
        return;
    }
    int mid=(l+r)>>1;
    update(x<<1,l,mid,L,R,v);
    update(x<<1|1,mid+1,r,L,R,v);
    sum[x]=sum[x<<1]+sum[x<<1|1];
}
inline void pushdown(int x,int l,int r)
{
    if(l==r)
    {
        pos[cnt++]=x;
        return;
    }
    int mid=(l+r)>>1;
    int ls=x<<1;
    int rs=ls+1;
    if(tag[x])
    {
        sum[ls]+=(mid-l+1)*tag[x];
        sum[rs]+=(r-mid)*tag[x];
        tag[ls]+=tag[x];
        tag[rs]+=tag[x];
        tag[x]=0;
    }
    pushdown(ls,l,mid);
    pushdown(rs,mid+1,r);
}
inline void cal(int x,int y)
{
    int fx=top[x],fy=top[y];
    while(fx!=fy)
    {
        if(dep[fx]<dep[fy])
        {
            swap(x,y);
            swap(fx,fy);
        }
        update(1,1,tot,l[fx],l[x],1);
        x=fa[fx];
        fx=top[x];
    }
    if(l[x]>l[y])
        swap(x,y);
    update(1,1,tot,l[x],l[y],1);
}
inline void dfs1(int s)
{
    size[s]=1;
    for(register int i=head[s];i;i=e[i].next)
    {
        int v=e[i].to;
        if(!dep[v])
        {
            dep[v]=dep[s]+1;
            fa[v]=s;
            dfs1(v);
            size[s]+=size[v];
            if(size[son[s]]<size[v])
                son[s]=v;
        }
    }
}
inline void dfs2(int x,int t)
{
    l[x]=++tot;
    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()
{
    scanf("%d",&n);
    for(register int i=1;i<=n;++i)
        scanf("%d",&route[i]);
    for(register int i=1;i<n;++i)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        add(x,y);
        add(y,x);
    }
    fa[1]=1;dep[1]=1;
    dfs1(1);
    dfs2(1,1);
    memset(sum,0,sizeof(sum));
    memset(tag,0,sizeof(tag));
    for(register int i=1;i<n;++i)
    {
        cal(route[i],route[i+1]);
        update(1,1,tot,l[route[i+1]],l[route[i+1]],-1);
    }
    pushdown(1,1,tot);
    for(register int i=1;i<=n;++i)
        cout<<sum[pos[l[i]]]<<"\n";
    return 0;
}

还是膜蛤好!!!

江来是要负泽任的,民不民白啊!

滋不滋磁啊!

坠吼坠吼的啊!

港记和美国的华莱士!

请不要思想江化!

我们要膜蛤,当一名hath

猜你喜欢

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