珂朵莉ODT70TLE求助
查看原帖
珂朵莉ODT70TLE求助
225813
SOSXX楼主2022/11/18 13:56
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cctype>
#include<cmath>
#include<set>
#include<algorithm>
typedef long long LL;
typedef unsigned long long ULL;
namespace FastIo{
    typedef __uint128_t ULLL;
    static char buf[100000],*p1=buf,*p2=buf,fw[100000],*pw=fw;
    #define gc p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++
    inline void pc(const char &ch){
        if(pw-fw==100000)fwrite(fw,1,100000,stdout),pw=fw;
        *pw++=ch;
    }
    #define fsh fwrite(fw,1,pw-fw,stdout),pw=fw
    struct FastMod{
        FastMod(ULL b):b(b),m(ULL((ULLL(1)<<64)/b)){}
        ULL reduce(ULL a){
            ULL q=(ULL)((ULLL(m)*a)>>64);
            ULL r=a-q*b;
            return r>=b?r-b:r;
        }
        ULL b,m;
    }HPOP(10);
    struct QIO{
        char ch;
        int st[40];
        inline char read(){
        	ch=gc;
        	if(ch<'a'||ch>'z')ch=gc;
        	return ch;
		}
        inline void read(int &x){
            x=0,ch=gc;
            while(!isdigit(ch))ch=gc;
            while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch^48);ch=gc;}
        }
        template<class T>inline void write(T a){
            do{st[++st[0]]=HPOP.reduce(a);a/=10;}while(a);
            while(st[0])pc(st[st[0]--]^48);
            pc('\n');
        }
    }qrw;
}
using namespace FastIo;
using std::set;
using std::iterator;
using std::swap;
#define NUMBER1 100000
#define ODT set<KDL>::iterator
#define P(A) A=-~A
#define fione_i(begin,end) for(register int i=begin;i<=end;P(i))
#define tt(u) for(register int i=head[u];i;i=e[i].next)
struct KDL{
	int l,r;
	mutable int v;
	KDL(int l,int r=0,LL v=0):l(l),r(r),v(v){}
	bool operator<(const KDL &A)const{return l<A.l;}
};
set<KDL>odt;
struct EDGE{int next,to;}e[(NUMBER1<<2)+5];
int depth[NUMBER1+5],size[NUMBER1+5],n,son[NUMBER1+5],top[NUMBER1+5],fa[NUMBER1+5],id[NUMBER1+5],tot(0),cnt(0),head[NUMBER1+5];
inline void add(const int &u,const int &v){e[++tot].next=head[u];head[u]=tot,e[tot].to=v;}
ODT split(int p){
	ODT it=odt.lower_bound(KDL(p));
	if(it!=odt.end()&&it->l==p)return it;
	--it;
	int l=it->l,r=it->r,v=it->v;
	odt.erase(it);
	odt.insert(KDL(l,p-1,v));
	return odt.insert(KDL(p,r,v)).first;
}
inline int assign(int l,int r,int date){
	ODT itr=split(r+1),itl=split(l);
	int sum1(0),sum2=date*(r-l+1);
	for(register ODT it=itl;it!=itr;++it)sum1+=(it->v)*((it->r)-(it->l)+1);
	odt.erase(itl,itr);
	odt.insert(KDL(l,r,date));
	return abs(sum2-sum1);
}
void dfs1(int u,int fath,int deep){
	fa[u]=fath,depth[u]=deep,size[u]=1;
	int ms(-1);
	tt(u){
		if(e[i].to==fath)continue;
		dfs1(e[i].to,u,deep+1);
		size[u]+=size[e[i].to];
		if(size[e[i].to]>ms)ms=size[e[i].to],son[u]=e[i].to;
	}
}
void dfs2(int u,int tf){
	id[u]=++cnt,top[u]=tf;
	if(!son[u])return;
	dfs2(son[u],tf);
	tt(u){
		if(e[i].to==fa[u]||e[i].to==son[u])continue;
		dfs2(e[i].to,e[i].to);
	}
}
inline int treechange(int x,int y){
	int sum(0);
	while(top[x]!=top[y]){
		if(depth[top[x]]<depth[top[y]])swap(x,y);
		sum+=assign(id[top[x]],id[x],1);
		x=fa[top[x]];
	}
	if(depth[x]>depth[y])swap(x,y);
	sum+=assign(id[x],id[y],1);
	return sum;
}
signed main(){
	qrw.read(n);
	int x,q;
	odt.insert(KDL(1,n+1,0));
	char z;
	fione_i(2,n){
		qrw.read(x);
		P(x);
		add(i,x);add(x,i);
	}
	dfs1(1,0,1);
	dfs2(1,1);
	qrw.read(q);
	while(q--){
		z=qrw.read();
		qrw.read(x);
		P(x);
		if(z=='i')qrw.write(treechange(1,x));
		else qrw.write(assign(id[x],id[x]+size[x]-1,0));
	}
    fsh;
    exit(0);
    return 0;
}
2022/11/18 13:56
加载中...