社区讨论

T了,70分,实在不知的如何优化

P2486[SDOI2011] 染色参与者 7已保存回复 7

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
7 条
当前快照
1 份
快照标识符
@mi5i6k0s
此快照首次捕获于
2025/11/19 12:29
4 个月前
此快照最后确认于
2025/11/19 12:29
4 个月前
查看原帖
应该是卡常了,写的正解,但真的不知道该如何改了
CPP
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=2e5+10;
struct jgt{
    int x,y,next;
} bian[2*maxn];
int n,m,cnt[4*maxn],lt[4*maxn],rt[4*maxn],mark[4*maxn],tot,right_mark,ql,qr,ans;
int deep[maxn],top[maxn],pos[maxn],val[maxn],son[maxn],size[maxn],w[maxn],head[maxn],fa[maxn];
int max(int a,int b){    if (a>b)  return a;    return b;}
int min(int a,int b){    if (a<b)  return a;    return b;}
inline void swap(int &x,int &y){    int temp=x;    x=y;    y=temp;}
void add_edge(int a,int b)
{
    tot++;
    bian[tot].x=a;
    bian[tot].y=b;
    bian[tot].next=head[a];
    head[a]=tot;
}
void build_tree(int now,int pre,int depth)
{
    int max=0;
    deep[now]=depth;
    fa[now]=pre;
    size[now]=1;
    for (int tmp=head[now];tmp!=-1;tmp=bian[tmp].next)
    {
        int v=bian[tmp].y;
        if (v!=pre)
        {
            build_tree(v,now,depth+1);
            size[now]+=size[v];
            if (max<size[now])  max=size[now],son[now]=v;
        }
    }
}
void get_id(int now,int high)
{
    pos[now]=++tot;
    val[tot]=w[now];
    top[now]=high;
    if (son[now])
      get_id(son[now],high);
    for (int tmp=head[now];tmp!=-1;tmp=bian[tmp].next)
    {
        int v=bian[tmp].y;
        if (v!=fa[now]&&v!=son[now])
          get_id(v,v);
    }
}
inline void pushup(int root)
{
    int lchild=2*root,rchild=2*root+1;
    lt[root]=lt[lchild];
    rt[root]=rt[rchild];
    cnt[root]=cnt[lchild]+cnt[rchild];
    if (rt[lchild]==lt[rchild])
        cnt[root]--;
}
inline void build_seg_tree(int root,int l,int r)
{
    if (l==r)
      cnt[root]=1,lt[root]=rt[root]=val[l];
    else
    {    
        int mid=(l+r)/2,lchild=2*root,rchild=2*root+1;
        build_seg_tree(lchild,l,mid);
        build_seg_tree(rchild,mid+1,r);
        pushup(root);
    }
}
inline void pushdown(int root)
{
    mark[2*root]=mark[2*root+1]=mark[root];
    lt[2*root]=rt[2*root]=lt[2*root+1]=rt[2*root+1]=mark[root];
    cnt[2*root]=cnt[2*root+1]=1;
    mark[root]=-1;
    return;
}
inline void seg_tree_query(int root,int l,int r)//区间查询
{
    if (ql<=l&&r<=qr)
    {
      ans+=cnt[root];
      if (lt[root]==right_mark)  ans--;
      right_mark=rt[root];
    }
    else
    {    
        int mid=(l+r)/2,lchild=2*root,rchild=2*root+1;
        if (mark[root]!=-1)  pushdown(root);
        if (ql<=mid)
          seg_tree_query(lchild,l,mid);
        if (qr>mid)
          seg_tree_query(rchild,mid+1,r);
    }
}
inline void update(int root,int l,int r,int co)//区间修改
{
    if (ql<=l&&r<=qr)
      mark[root]=co,lt[root]=rt[root]=co,cnt[root]=1;
    else
    {    
        int mid=(l+r)/2,lchild=2*root,rchild=2*root+1;
        if (mark[root]!=-1)  pushdown(root);
        if (ql<=mid)
          update(lchild,l,mid,co);
        if (qr>mid)
          update(rchild,mid+1,r,co);
        pushup(root);
    }
}
inline int seg_tree_point_query(int root,int l,int r)//单点查询
{

    if (l==r)
      return rt[root];
    else
    {    
        int mid=(l+r)/2,lchild=2*root,rchild=2*root+1;
        if (mark[root]!=-1)  pushdown(root);
        if (ql<=mid)
          return seg_tree_point_query(lchild,l,mid);
        else 
          return seg_tree_point_query(rchild,mid+1,r);
    }
}
inline void query(int x,int y)链查询
{
    int l,r;
    while (top[x]!=top[y])
    {
        if (deep[top[x]]<deep[top[y]]) swap(x,y);
        ql=pos[top[x]],qr=pos[x];
        right_mark=0;
        seg_tree_query(1,1,n);
        ql=qr=pos[top[x]];
        if (fa[top[x]]!=0)
        {
        int tmp1=seg_tree_point_query(1,1,n);
        ql=qr=pos[fa[top[x]]];
        int tmp2=seg_tree_point_query(1,1,n);
        if (tmp1==tmp2)
           ans--;
        }
         x=fa[top[x]];
     }
    if (pos[x]>pos[y]) swap(x,y);
    ql=pos[x],qr=pos[y];
    right_mark=0;
    seg_tree_query(1,1,n);
}
inline void update_c(int x,int y,int z)//链修改
{
    int l,r;
    while (top[x]!=top[y])
    {
        if (deep[top[x]]<deep[top[y]]) swap(x,y);
        ql=pos[top[x]],qr=pos[x];
        update(1,1,n,z);
        x=fa[top[x]];
    }
    if (pos[x]>pos[y]) swap(x,y);
    ql=pos[x],qr=pos[y];
    update(1,1,n,z);
}

int main()
{
    int i,a,b,c;
    char opt[5];
    memset(mark,-1,sizeof(mark));
    memset(head,-1,sizeof(head));
    scanf("%d%d",&n,&m);
    for (i=1;i<=n;i++)
      scanf("%d",&w[i]);
    for (i=1;i<=n-1;i++)
      scanf("%d%d",&a,&b),add_edge(a,b),add_edge(b,a);
    tot=0;
    build_tree(1,0,1);
    get_id(1,1);
    build_seg_tree(1,1,n);
    for (i=1;i<=m;i++)
    {
        ans=0;
        right_mark=0;
        scanf("%s",&opt);
        if (opt[0]=='Q')
          scanf("%d%d",&a,&b),query(a,b),printf("%d\n",ans);//查询
        else
          scanf("%d%d%d",&a,&b,&c),update_c(a,b,c);//更改
    }
}

回复

7 条回复,欢迎继续交流。

正在加载回复...