标签:namespace wap memset add 区间 bottom ems lse 很多
考试的时候直接扎第一题上了这到题连暴力都没打出来T_T;
心路历程:
当时想到了离散化(很慌没打出来。。。),树上差分,lca倍增,当时觉滴倍增很难打,一看n<100000,于是选择
用向上标记法,然而少了一行代码,,,,爆零两行泪。。。
现在看来倍增真是一点不难啊好打有好用,所以不要有为难情绪,刚就完了。
之所以没想到线段树合并是因为当时真的没有透彻理解,所以总结发现新知识点还是要知道它能干什么,知道它的优点。。。
}
离散化用来干掉1->10^9,考试的时候真的傻认为要是有10^9种不就玩了吗,,,然后发现还有m次操作这东东,所以z离散化后len最大也就m个卡掉了很多
所以得离线来做(我承认现在才知道离线在线是嘛玩意。。丢人啊。。。)
每个点有很多信息所以权值线段树用来优化空间(当然也能优化时间),对每个点动态开树插入和删除(lca,f[lca]),最后dfs,父亲合并儿子。
所以需维护区间的maxcnt以及其id,在merge时就需要多传一下l,r(1,len),如果l==r更新maxx值和id,需要注意的是如果maxx<=0,id干成0(题目要求)。
sd错误:merge时忘了加上root[x]=merge,如果root[x]=0,就会...炸。还有空间没开够得开到maxn*50。
优化:插入时如果lca==x||lca==y,那就插入了一次删了一次所以干脆不插入。。。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=100050;
bool mark[maxn];
int n,m,t,ans[maxn],len;
int kpx[maxn],kpy[maxn],kpz[maxn],turn[maxn];//离线离散化
int deep[maxn],f[maxn][20];//倍增lca
int sz,root[maxn],cnt[maxn*50],lc[maxn*50],rc[maxn*50],maxx[maxn*50],num[maxn*50];//线段树
int head[maxn],cntn=1;
struct node{
int to,next;
}line[maxn*2];
void add(int x,int y)
{
line[cntn].to=y;
line[cntn].next=head[x];
head[x]=cntn++;
}
void dfs(int x)
{
for(int i=head[x];i;i=line[i].next)
{
int v=line[i].to;
if(!mark[v])
{
mark[v]=1;
deep[v]=deep[x]+1;
f[v][0]=x;
for(int j=1;j<=t;j++