开学了来刷刷水。
开个map每个值随便开个数据结构。卡了$O(nlog^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);
}
}
}
要是人生能有追求就好了。
恋をしようか。