BZOJ4999: This Problem Is Too Simple!

开学了来刷刷水。

开个map每个值随便开个数据结构。卡了$O(n\log^2n)$的map版树状数组差评。

卡了半天才rk1,应该没几天就没了。已经没了。

/**************************************************************
    Problem: 4999
    User: T404
    Language: C++
    Result: Accepted
    Time:2900 ms
    Memory:164208 kb
****************************************************************/
 
#include<cstdio>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
#include<sys/mman.h>
struct ano{
    char b[1<<21],*s,*t;
    ano():t(b){
        s=(char*)mmap(0,1<<25,1,2,0,0);
    }
    ~ano(){fwrite(b,1,t-b,stdout);}
    char get(){
        while(*s<33)++s;
        return*s++;
    }
    void out(const char*v){
        while(*v)*t++=*v++;
        *t++=10;
    }
    operator int(){
        int x=0,y=0;
        while(*s<48)
            *s++==45?y=1:0;
        while(*s>32)
            x=x*10+*s++-48;
        return y?-x:x;
    }
    void out(int x){
        static char c[12];
        char*i=c;
        if(!x)*t++=48;
        else{
            if(x<0)*t++=45,x=-x;
            while(x){
                int y=x/10;
                *i++=x-y*10+48,x=y;
            }
            while(i!=c)*t++=*--i;
        }
        *t++=10;
    }
}buf;
using namespace std;
const int N=1e5+5;
struct edge{
    int v;
    edge*s;
}e[N*2];
edge*o=e,*h[N];
int dfn,f1[N],f2[N],siz[N],p[N],d[N],c1[N],c2[N],w[N];
void dfs1(int u){
    f1[u]=++dfn;
    siz[u]=1;
    for(edge*i=h[u];i;i=i->s)
        if(i->v!=p[u]){
            d[i->v]=d[p[i->v]=u]+1;
            dfs1(i->v);
            siz[u]+=siz[i->v];
            if(siz[c1[u]]<siz[i->v])
                c1[u]=i->v;
        }
    f2[u]=dfn;
}
int lca(int u,int v){
    while(c2[u]!=c2[v])
        d[c2[u]]>d[c2[v]]?u=p[c2[u]]:v=p[c2[v]];
    return d[u]<d[v]?u:v;
}
struct node{
    node*i,*j;
    int s;
}a[N*102];
node*l=a;
__gnu_pbds::cc_hash_table<int,node*>t;
void inc(int d,int u,node**o){
    for(int i=16;~i;--i){
        if(!*o)*o=l++;
        if(u>>i&1)o=&(*o)->j;
        else
            (*o)->s+=d,o=&(*o)->i;
    }
}
int ask(int u,node*o){
    int s=0;
    for(int i=16;~i;--i){
        if(!o)break;
        if(~u>>i&1)o=o->i;
        else
            s+=o->s,o=o->j;
    }
    return s;
}
void inc(int u,int d){
    node**o=&t[w[u]];
    inc(d,f1[u]-1,o);
    inc(-d,f2[u],o);
}
int ask(int u,int v,int k){
    node*o=t[k];
    int a=lca(u,v);
    return ask(f1[u],o)+ask(f1[v],o)-ask(f1[a],o)*2+(w[a]==k);
}
int main(){
    int n,m,u,v;
    n=buf,m=buf;
    for(int i=1;i<=n;++i)
        w[i]=buf;
    for(int i=2;i<=n;++i){
        u=buf,v=buf;
        *o={v,h[u]};
        h[u]=o++;
        *o={u,h[v]};
        h[v]=o++;
    }
    dfs1(1);
    for(int i=1;i<=n;++i)
        if(c1[p[i]]!=i)
            for(int j=i;j;j=c1[j])c2[j]=i;
    for(int i=1;i<=n;++i)
        inc(i,1);
    while(m--){
        char o=buf.get();
        u=buf,v=buf;
        if(o=='Q')
            buf.out(ask(u,v,buf));
        else{
            inc(u,-1);
            w[u]=v;
            inc(u,1);
        }
    }
}

要是人生能有追求就好了。

恋をしようか。

转载于:https://www.cnblogs.com/f321dd/p/7465071.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值