您的位置:首页 > 博客中心 > 互联网 >

bzoj3307:雨天的尾巴

时间:2022-05-07 16:30

树上差分+线段树合并+离散化
对于修改的路径,树上差分就好了
代码:

#include
#include
#include
#include
#include
using namespace std;
void read(int &x) {
    char ch; bool ok;
    for(ok=0,ch=getchar(); !isdigit(ch); ch=getchar()) if(ch=='-') ok=1;
    for(x=0; isdigit(ch); x=x*10+ch-'0',ch=getchar()); if(ok) x=-x;
}
#define rg register
const int maxn=1e5+10;
int dep[maxn],n,m,id,tot,pre[maxn*2],rt[maxn],ls[maxn*50],f[maxn][20],x[maxn],y[maxn],z[maxn],nid[maxn];
int rs[maxn*50],mx[maxn*50],mxid[maxn*50],nxt[maxn*2],h[maxn],cnt,ans[maxn],w[maxn];tr1::unordered_mapmp;
bool vis[maxn];
void add(int x,int y)
{
    pre[++cnt]=y,nxt[cnt]=h[x],h[x]=cnt;
    pre[++cnt]=x,nxt[cnt]=h[y],h[y]=cnt;
}
void dfs(int x,int fa)
{
    for(rg int i=1;i<20;i++)
    {
        if((1<dep[x])break;
        f[x][i]=f[f[x][i-1]][i-1];
    }
    for(rg int i=h[x];i;i=nxt[i])
        if(pre[i]!=fa)f[pre[i]][0]=x,dep[pre[i]]=dep[x]+1,dfs(pre[i],x);
}
int lca(int x,int y)
{
    if(dep[x]>dep[y])swap(x,y);
    int poor=dep[y]-dep[x];
    for(rg int i=19;i>=0;i--)if(poor&(1<=0;i--)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
    return x==y?x:f[x][0];
}
void update(int x)
{
    if(mx[ls[x]]>mx[rs[x]]||(mx[ls[x]]==mx[rs[x]]&&mxid[ls[x]]mxid[rs[x]]))mx[x]=mx[rs[x]],mxid[x]=mxid[rs[x]];
}
void change(int &k,int l,int r,int a,int b)
{
    if(!k)k=++id;int mid=(l+r)>>1;
    if(l==r){mx[k]+=b,mxid[k]=l;return ;}
    if(a<=mid)change(ls[k],l,mid,a,b);
    else change(rs[k],mid+1,r,a,b);
    update(k);
}
int merge(int x,int y,int l,int r)
{
    if(!x||!y)return x+y;
    int mid=(l+r)>>1;
    ls[x]=merge(ls[x],ls[y],l,mid);
    rs[x]=merge(rs[x],rs[y],mid+1,r);
    if(l==r)mx[x]+=mx[y];else update(x);
    return x;
}
void solve(int x,int fa)
{
    for(rg int i=h[x];i;i=nxt[i])
        if(pre[i]!=fa)
        {
            solve(pre[i],x);
            rt[x]=merge(rt[x],rt[pre[i]],1,tot);
        }
    ans[x]=nid[mxid[rt[x]]];
}
int main()
{
    read(n),read(m);
    for(rg int i=1,x,y;i

本类排行

今日推荐

热门手游