社区讨论
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 条回复,欢迎继续交流。
正在加载回复...