점분 치 와 점분 수

254002 단어 데이터 구조
글 목록
토로
제목
  • [IOI2011]Race
  • cf716 E. Digit Tree
  • cf293 E. Close Vertices

  • 충격파
  • cf757 G. Can Bash Save the Day?

  • 구유
    작년 에 은퇴 시 켜 준 좋 은 물건.한 문 제 를 쓰 고 나 면 내 가 이미 동태 적 으로 분 리 를 할 수 있다 고 생각 하 는 나 는 정말 too young too simple, sometimes naive. 지금 은 적어도 작년 처럼 머리 를 쥐 어 뜯 고 템 플 릿 을 쓰 지 않 는 다.그러나 거 위 는 나의 작은 bug 더미 에 영향 을 주지 않 는 다.이 배열 은 경 계 를 넘 었 습 니 다. 그곳 은 비우 지 않 았 습 니 다. 그곳 은 변수 가 바 뀌 었 습 니 다.
    제목.
    [IOI2011]Race
    내 마음 을 무 너 뜨리 는 좋 은 본보기.더 이상 평범 할 수 없 는 분할 치료 양식 이지 만 거 위 는 죽어도 조절 할 수 없다.코드 를 재 구성 하 는 것 은 그래도 마지막 에 어떻게 고 치 는 지 나 도 어디로 가 야 할 지 모 르 겠 어.대략 d [0] 는 n 과 tot - sz [x] 로 부 여 됩 니 다.이 거 교 는 아들 과 나의 sz 의 크기 관 계 를 직접 판단 하여 아들 의 실제 sz 를 얻 었 다.どこでもドア
    //Achen
    #include
    #define For(i,a,b) for(int i=(a);i<=(b);i++)
    #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
    #define Formylove return 0
    const int N=200007,M=1000007;
    typedef long long LL;
    typedef double db;
    using namespace std;
    int n,m,ans,K,d[M];
    
    template<typename T> void read(T &x) {
        char ch=getchar(); T f=1; x=0;
        while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
        if(ch=='-') f=-1,ch=getchar();
        for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    }
    
    int ecnt,fir[N],nxt[N<<1],to[N<<1],val[N<<1];
    void add(int u,int v,int w) {
        nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v; val[ecnt]=w;
        nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u; val[ecnt]=w;
    }
    
    int RT,sz[N],msz[N],vis[N];
    void get_root(int x,int fa,int tot) {
        sz[x]=msz[x]=1;
        for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa&&!vis[to[i]]) {
            get_root(to[i],x,tot);
            sz[x]+=sz[to[i]];
            msz[x]=max(msz[x],sz[to[i]]);
        }
        msz[x]=max(msz[x],tot-sz[x]);
        if(!RT||msz[x]<msz[RT]) RT=x;
    }
    
    int sta[N],R[N],H[N],top;
    void dfs(int x,int fa,int now,int cc) {
        if(now>K) return;
        sta[++top]=x; 
        R[x]=cc; H[x]=now; 
        ans=min(ans,d[K-now]+cc);
        for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa&&!vis[to[i]]) 
            dfs(to[i],x,now+val[i],cc+1);
    }
    
    void solve(int x,int tot) {
        vis[x]=1; int pr=0;
        for(int i=fir[x];i;i=nxt[i]) if(!vis[to[i]]) {
            dfs(to[i],x,val[i],1);
            For(i,pr+1,top) d[H[sta[i]]]=min(d[H[sta[i]]],R[sta[i]]); pr=top;
        }
        while(top) d[H[sta[top--]]]=n; d[0]=0;
        for(int i=fir[x];i;i=nxt[i]) if(!vis[to[i]]) {
            RT=0; int lsz=sz[to[i]]>sz[x]?tot-sz[x]:sz[to[i]];
            get_root(to[i],x,lsz); solve(RT,lsz);
        }
    }
    
    int main() {
        //freopen("1.in","r",stdin);
        //freopen("1.out","w",stdout);
        read(n); read(K);
        For(i,1,K) d[i]=n; ans=n;
        For(i,2,n) {
        	int u,v,w;
        	read(u); read(v); read(w);
        	add(u+1,v+1,w);
        }
        get_root(1,0,n); solve(1,n);
        if(ans==n) ans=-1;
        printf("%d
    "
    ,ans); Formylove; }

    cf716 E. Digit Tree
    ............................................................................................
    경 로 를 반 으로 나 누 면 l v 는 8727 ° 1 0 d e p r + r v. 1.  ( m o d   p ) lv*10^{dep_r}+rv \equiv 0\ (mod\ p) lv∗10depr​+rv≡0 (mod p) 전형 점.(p, 10) = 1 exgcd 로 10 의 역 원 을 구하 라 고 합 니 다.
    //Achen
    #include
    #define For(i,a,b) for(int i=(a);i<=(b);i++)
    #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
    #define Formylove return 0
    const int N=100007;
    typedef long long LL;
    typedef double db;
    using namespace std;
    int n,p;
    LL ans,pr[N],prinv[N];
    
    template<typename T> void read(T &x) {
    	char ch=getchar(); T f=1; x=0;
    	while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    	if(ch=='-') f=-1,ch=getchar();
    	for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    }
    
    int ecnt,fir[N],nxt[N<<1],to[N<<1],val[N<<1];
    void add(int u,int v,int w) {
    	nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v; val[ecnt]=w;
    	nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u; val[ecnt]=w;
    }
    
    int RT,sz[N],msz[N],vis[N];
    void get_root(int x,int fa,int tot) {
    	sz[x]=msz[x]=1;
    	for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa&&!vis[to[i]]) {
    		get_root(to[i],x,tot);
    		sz[x]+=sz[to[i]];
    		msz[x]=max(msz[x],sz[to[i]]);
    	}
    	msz[x]=max(msz[x],tot-sz[x]);
    	if(!RT||msz[x]<msz[RT]) RT=x;
    }
    
    int sta[N],top,Lv[N],Rv[N],dep[N];
    void dfs(int x,int fa,int R,int lv,int rv) {
    	sta[++top]=x;
    	dep[x]=R; Lv[x]=lv; Rv[x]=rv;
    	if(lv%p==0) ans++;
    	if(rv%p==0) ans++;
    	for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa&&!vis[to[i]])
    		dfs(to[i],x,R+1,(pr[R]*val[i]+lv)%p,((LL)rv*10+val[i])%p);
    }
    
    void exgcd(LL a,LL b,LL &d,LL &x,LL &y) {
    	if(!b) { d=a; x=1; y=0; return; }
    	exgcd(b,a%b,d,y,x); y-=a/b*x;
    }
    LL get_inv(int a,int p) {
    	LL d,x,y; exgcd(a,p,d,x,y);
    	return (x%p+p)%p;
    }
    
    map<int,int>mp;
    void calc(int l,int r,int f) {
    	For(i,l,r) {
    		int x=sta[i],v=((LL)p-Rv[x])%p*prinv[dep[x]]%p;
    		ans+=f*mp[v]; mp[Lv[x]]++;
    	}
    	For(i,l,r) mp[Lv[sta[i]]]--;
    	Rep(i,r,l) {
    		int x=sta[i],v=((LL)p-Rv[x])%p*prinv[dep[x]]%p;
    		ans+=f*mp[v]; mp[Lv[x]]++;
    	}
    	For(i,l,r) mp[Lv[sta[i]]]--; 
    }
    
    void solve(int x,int tot) {
    	vis[x]=1;
    	int szx=sz[x],prtop=0; 
    	for(int i=fir[x];i;i=nxt[i]) if(!vis[to[i]]) {
    		dfs(to[i],x,1,val[i],val[i]); 
    		calc(prtop+1,top,-1); prtop=top;
    	}
    	calc(1,top,1); top=0;
    	for(int i=fir[x];i;i=nxt[i]) if(!vis[to[i]]) {
    		RT=0; int lsz=sz[to[i]]>szx?tot-szx:sz[to[i]];
    		get_root(to[i],x,lsz); solve(RT,lsz);
    	}
    }
    
    int main() {
        //freopen("1.in","r",stdin);
        //freopen("3730.out","w",stdout);
        read(n); read(p);
        pr[0]=1; prinv[0]=1;
    	prinv[1]=get_inv(10,p);
    	For(i,1,n) {
    		pr[i]=pr[i-1]*10%p;
    		if(i>1) prinv[i]=prinv[i-1]*prinv[1]%p;
    	}
        For(i,2,n) {
        	int u,v,w;
        	read(u); read(v); read(w);
        	add(u+1,v+1,w%p);
    	}
    	get_root(1,0,n);
    	solve(RT,n);
    	printf("%I64d
    "
    ,ans); Formylove; }

    cf293 E. Close Vertices
    .................................................................................1 차원 정렬 더 블 포인터 1 차원 트 리 배열 하면 됩 니 다.작은 틀
    //Achen
    #include
    #define For(i,a,b) for(int i=(a);i<=(b);i++)
    #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
    #define Formylove return 0
    const int N=100007;
    typedef long long LL;
    typedef double db;
    using namespace std;
    int n,L,W;
    LL ans;
    
    template<typename T> void read(T &x) {
    	char ch=getchar(); T f=1; x=0;
    	while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    	if(ch=='-') f=-1,ch=getchar();
    	for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    }
    
    int ecnt,fir[N],nxt[N<<1],to[N<<1],val[N<<1];
    void add(int u,int v,int w) {
    	nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v; val[ecnt]=w;
    	nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u; val[ecnt]=w;
    }
    
    int RT,sz[N],msz[N],vis[N];
    void get_root(int x,int fa,int tot) {
    	sz[x]=msz[x]=1;
    	for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa&&!vis[to[i]]) {
    		get_root(to[i],x,tot);
    		sz[x]+=sz[to[i]];
    		msz[x]=max(msz[x],sz[to[i]]);
    	}
    	msz[x]=max(msz[x],tot-sz[x]);
    	if(!RT||msz[x]<msz[RT]) RT=x;
    }
    
    int sta[N],top,R[N],H[N];
    void dfs(int x,int fa,int now,int cc) {
    	if(now>W||cc>L) return;
    	else ans++;
    	R[x]=cc; 
    	H[x]=now;
    	sta[++top]=x;
    	for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa&&!vis[to[i]])
    		dfs(to[i],x,now+val[i],cc+1);
    }
    
    int cmp(const int &A,const int &B) { return H[A]<H[B]||(H[A]==H[B]&&R[A]<R[B]); }	
    
    int sum[N];
    void add(int x,int v) {
    	for(int i=x;i<=L;i+=(i&(-i)))
    		sum[i]+=v;
    }
    
    int qry(int x) {
    	int rs=0;
    	for(int i=x;i;i-=(i&(-i)))
    		rs+=sum[i];
    	return rs;
    }
    
    int a[N],le;
    void calc(int l,int r,int f) {
    	le=r-l+1; int np=0;
    	For(i,l,r) a[i-l+1]=sta[i];
    	sort(a+1,a+le+1,cmp);
    	For(i,1,le) {
    		while(np&&H[a[np]]+H[a[i]]>W) {
    			add(R[a[np]],-1); np--;
    		}
    		ans+=f*qry(L-R[a[i]]);
    		if(i<le&&H[a[i]]+H[a[i+1]]<=W) {
    			np++; add(R[a[i]],1);
    		}
    	}
    	For(i,1,np) add(R[a[i]],-1);
    }
    
    void solve(int x,int tot) {
    	vis[x]=1;
    	int szx=sz[x],prtop=0; 
    	for(int i=fir[x];i;i=nxt[i]) if(!vis[to[i]]) {
    		dfs(to[i],x,val[i],1); 
    		calc(prtop+1,top,-1); prtop=top;
    	}
    	calc(1,top,1); top=0;
    	for(int i=fir[x];i;i=nxt[i]) if(!vis[to[i]]) {
    		RT=0; int lsz=sz[to[i]]>szx?tot-szx:sz[to[i]];
    		get_root(to[i],x,lsz); solve(RT,lsz);
    	}
    }
    
    int main() {
        //freopen("1.in","r",stdin);
        //freopen("3730.out","w",stdout);
        read(n); read(L); read(W);
        For(i,2,n) {
        	int u,v;
        	read(u); read(v);
        	add(i,u,v);
    	}
    	get_root(1,0,n);
    	solve(RT,n);
    	printf("%I64d
    "
    ,ans); Formylove; }

    충격파
    등...........................................................................포인터 동적 할당 메모리 트 리 배열 도 너무 좋 죠?근 데 조회 할 때 는 up 과 min 을 가 져 가 야 돼 요. 안 그러면 RE 잖 아 요!그리고 나 에 게 나무 에 있 는 모든 조상 과 내 가 그들 에 게 가 는 거 리 를 기록 하 세 요. 예전 에 나 는 lca 에 게 거 리 를 찾 아 달라 고 썼 습 니 다. 바보 가 아 닙 니까?각각 두 개의 나무 모양 의 배열 에 서브 트 리 안의 점 을 담 고 하 나 는 자신의 거 리 를 누 르 고 하 나 는 자신의 점 에 따라 아버지의 거 리 를 나눈다.
    //Achen
    #include
    #define For(i,a,b) for(int i=(a);i<=(b);i++)
    #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
    #define Formylove return 0
    const int N=100007;
    typedef long long LL;
    typedef double db;
    using namespace std;
    int n,m,val[N],tmp1[N*30],tmp2[N*30];
    
    template<typename T> void read(T &x) {
    	char ch=getchar(); T f=1; x=0;
    	while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    	if(ch=='-') f=-1,ch=getchar();
    	for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    }
    
    int ecnt,fir[N],nxt[N<<1],to[N<<1];
    void add(int u,int v) {
    	nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v;
    	nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u;
    }
    
    int RT,sz[N],msz[N],vis[N];
    void get_root(int x,int fa,int tot) {
    	sz[x]=msz[x]=1;
    	for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa&&!vis[to[i]]) {
    		get_root(to[i],x,tot);
    		sz[x]+=sz[to[i]];
    		msz[x]=max(msz[x],sz[to[i]]);
    	}
    	msz[x]=max(msz[x],tot-sz[x]);
    	if(!RT||msz[x]<msz[RT]) RT=x;
    }
    
    int *sum[2][N],*np1=tmp1+1,*np2=tmp2+1;
    void ADD(int o,int id,int x,int v) {
    	for(int i=x;i<=sz[id];i+=(i&(-i)))
    		sum[o][id][i]+=v;
    }
    
    int qry(int o,int id,int x) {
    	int rs=0;
    	for(int i=min(sz[id],x);i;i-=(i&(-i)))
    		rs+=sum[o][id][i];
    	return rs;
    }
    
    vector<int>ds[N];
    void dfs(int x,int fa,int R) {
    	ds[x].push_back(R); 
    	for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa&&!vis[to[i]]) 
    		dfs(to[i],x,R+1);
    }
    
    int p[N][20],dis[N][20];
    void build(int x,int tot) {
    	vis[x]=1;
    	int szx=sz[x]; 
    	sz[x]=tot;
    	p[x][0]=x;
    	dfs(x,0,0); 
    	sum[0][x]=np1; sum[1][x]=np2; 
    	np1+=sz[x]+1; np2+=sz[x]+1;
    	int up=ds[x].size()-1;
    	For(i,0,18) {
    		if(i>1) p[x][i]=p[p[x][1]][i-1];
    		if(p[x][i]) dis[x][i]=ds[x][up--];
    	}
    	For(i,0,18) if(p[x][i]) {
    		ADD(0,p[x][i],dis[x][i]+1,val[x]);
    		if(p[x][i+1]) ADD(1,p[x][i],dis[x][i+1],val[x]);
    	}
    	for(int i=fir[x];i;i=nxt[i]) if(!vis[to[i]]) {
    		RT=0; int lsz=sz[to[i]]>szx?tot-szx:sz[to[i]];
    		get_root(to[i],x,lsz); p[RT][1]=x; build(RT,lsz);
    	}
    }
    
    void change(int x,int y) {
    	For(i,0,18) if(p[x][i]) {
    		ADD(0,p[x][i],dis[x][i]+1,y-val[x]);
    		if(p[x][i+1]) ADD(1,p[x][i],dis[x][i+1],y-val[x]);
    	}
    	val[x]=y;
    }
    
    int lastans;
    void Qry(int x,int k) {
    	int rs=0;
    	For(i,0,18) {
    		if(!p[x][i]) break;
    		if(k>=dis[x][i]) rs+=qry(0,p[x][i],k-dis[x][i]+1);
    		if(p[x][i+1]&&k>dis[x][i+1]) rs-=qry(1,p[x][i],k-dis[x][i+1]);
    	}
    	printf("%d
    "
    ,rs); lastans=rs; } int main() { //freopen("3730.in","r",stdin); //freopen("3730.out","w",stdout); read(n); read(m); For(i,1,n) read(val[i]); For(i,2,n) { int u,v; read(u); read(v); add(u,v); } get_root(1,0,n); build(1,n); For(i,1,m) { int op,x,y; read(op); read(x); read(y); x^=lastans; y^=lastans; if(!op) Qry(x,y); else change(x,y); } Formylove; }

    cf757 G. Can Bash Save the Day?
    ................................................................................................q 개 동작 이 있 습 니 다:
    1 l r x: 문의 ∑ i = l r d i s t (p i, x) \ \ sum \ \ limits{i=l}^r dist(p_i,x) i=l∑r​dist(pi​,x) 2 x: s w a p ( p x , p x + 1 ) swap(p_x,p_{x+1}) swap(px​,px+1​)
    n , q ≤ 2 × 1 0 5 n,q\le 2\times 10^5 n,q≤2×105, 강제 온라인.
    강사 가 이것 은 지속 가능 한 나무 라 고 말 했 는데, 나 는 이것 이 set 물 을 건 널 수 있 지 않 겠 습 니까?그리고 즐겁게 때 리 고 즐겁게 T 를 했 어 요.각 점 은 set 로 관할 범 위 를 유지 하 는 점 이 a 의 순서 로 접두사 와 두 개의 log 이 고 70 여 개의 점 이 있 을 때 TLE 입 니 다.
    //Achen
    #include
    #define For(i,a,b) for(int i=(a);i<=(b);i++)
    #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
    #define Formylove return 0
    const int N=2e5+7;
    typedef long long LL;
    typedef double db;
    using namespace std;
    int n,m,a[N],p[N];
    
    template<typename T> void read(T &x) {
        char ch=getchar(); T f=1; x=0;
        while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
        if(ch=='-') f=-1,ch=getchar();
        for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    }
    
    struct node {
        int pos; LL sum[3];
        friend bool operator <(const node&A,const node&B) {
            return A.pos<B.pos;
        }
    };
    set<node>rt[N];
    
    int ecnt,fir[N],nxt[N<<1],to[N<<1],val[N<<1];
    void add(int u,int v,int w) {
        nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v; val[ecnt]=w;
        nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u; val[ecnt]=w;
    }
    
    int RT,sz[N],msz[N],vis[N];
    void get_root(int x,int fa,int tot) {
        sz[x]=msz[x]=1;
        for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa&&!vis[to[i]]) {
            get_root(to[i],x,tot);
            sz[x]+=sz[to[i]];
            msz[x]=max(msz[x],sz[to[i]]);
        }
        msz[x]=max(msz[x],tot-sz[x]);
        if(!RT||msz[RT]>msz[x]) RT=x;
    }
    
    vector<LL>ds[N];
    int sta[N],top;
    void dfs(int x,int fa,LL R) {
        sta[++top]=x;
        ds[x].push_back(R);
        for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa&&!vis[to[i]]) 
            dfs(to[i],x,R+val[i]);
    }
    
    bool cmp(const int&A,const int&B) { return p[A]<p[B]; }
    
    int f[N][20];
    LL dis[N][20];
    void build(int x,int tot) {
        vis[x]=1;
        top=0;
        dfs(x,0,0);
        sort(sta+1,sta+top+1,cmp);
        LL s1=0,s2=0,s3=0;
        For(i,1,top) {
            int u=sta[i],up=ds[u].size()-1;
            s1++; s2+=ds[u][up]; s3+=(up>0?ds[u][up-1]:0);
            rt[x].insert((node){p[u],s1,s2,s3});
        }
        f[x][0]=x; int up=ds[x].size()-1;
        For(i,0,18) {
            if(i>1) f[x][i]=f[f[x][1]][i-1];
            if(f[x][i]) dis[x][i]=ds[x][up--];
        }
        for(int i=fir[x];i;i=nxt[i]) if(!vis[to[i]]) {
            RT=0; int lsz=sz[to[i]]>sz[x]?tot-sz[x]:sz[to[i]];
            assert(lsz*2<=tot+5);
            get_root(to[i],x,lsz);
            f[RT][1]=x; build(RT,lsz);
        }
    }
    
    #define IT set::iterator 
    LL lastans;
    void qry(int ql,int qr,int x) {
        LL rs=0;
        For(i,0,18) if(f[x][i]) {
            int y=f[x][i];
            IT it=rt[y].lower_bound((node){ql,0}); 
            if(it==rt[y].end()) continue;
            if(it!=rt[y].begin()) {
                --it; rs-=((*it).sum[1]+(*it).sum[0]*dis[x][i]);
                if(f[x][i+1]) rs+=((*it).sum[2]+(*it).sum[0]*dis[x][i+1]);
            }
            it=rt[y].lower_bound((node){qr,0});
            node tpp=*it;
            if(it==rt[y].end()||(*it).pos>qr) {
                if(it==rt[y].begin()) continue;
                --it;
            }
            tpp=*it;
            rs+=((*it).sum[1]+(*it).sum[0]*dis[x][i]);
            if(f[x][i+1]) rs-=((*it).sum[2]+(*it).sum[0]*dis[x][i+1]);
        }
        printf("%lld
    "
    ,rs); lastans=rs; } void change(int x) { For(i,0,18) if(f[a[x]][i]) { int u=f[a[x]][i]; IT it=rt[u].lower_bound((node){x}); node tp=*it; rt[u].erase(it); it=rt[u].lower_bound((node){x}); if(it!=rt[u].end()&&(*it).pos==x+1) { node tp2=*it; LL t1=tp.sum[1]-dis[a[x]][i]+tp2.sum[1]-tp.sum[1]; LL t2=tp.sum[2]-dis[a[x]][i+1]+tp2.sum[2]-tp.sum[2]; rt[u].insert((node){x,tp.sum[0],t1,t2}); } else { tp.pos++; rt[u].insert(tp); } } For(i,0,18) if(f[a[x+1]][i]) { int u=f[a[x+1]][i]; IT it=rt[u].lower_bound((node){x+1,0}),it2=it; if(it2!=rt[u].begin()) it2--; if((*it2).pos==x) break; node t=*it; t.pos--; rt[u].erase(it); rt[u].insert(t); } swap(a[x],a[x+1]); p[a[x]]=x; p[a[x+1]]=x+1; } int main() { //freopen("1.in","r",stdin); //freopen("WA.out","w",stdout); read(n); read(m); For(i,1,n) read(a[i]),p[a[i]]=i; For(i,2,n) { int u,v,w; read(u); read(v); read(w); add(u,v,w); } RT=0; get_root(1,0,n); build(RT,n); For(i,1,m) { int op,x,l,r; read(op); if(op==1) { read(l); read(r); read(x); l^=lastans%(1<<30); r^=lastans%(1<<30); x^=lastans%(1<<30); qry(l,r,x); } else { read(x); x^=lastans%(1<<30); change(x); } } Formylove; }

    어 쩔 수 없어. 나 무 를 오래 갈 수 밖 에 없어...a 의 순서에 따라 지난 번 에 나 무 를 만 들 었 습 니 다. 각 점 은 현재 기여 한 점 수 를 유지 하고 아버지 와 의 거리 와 매번 체인 을 새로 만 듭 니 다.수정 은 x 라 는 나무 에 만 영향 을 주 고 앞 뒤의 나 무 는 변 하지 않 기 때문에 x - 1 을 바탕 으로 새로운 x 를 만 들 면 됩 니 다.그리고 지속 가능 해 야 하기 때문에 두 갈래 를 강제로 돌려 야 한다.밑 에서 위로 올 라 가 는 우수한 점 수 를 억지로 위 에서 아래로 나 누 는 추악 한 물건 으로 만 들 었 다.
    //Achen
    #include
    #define For(i,a,b) for(register int i=(a);i<=(b);i++)
    #define Rep(i,a,b) for(register int i=(a);i>=(b);i--)
    #define Formylove return 0
    const int N=2e5+7;
    typedef long long LL;
    typedef double db;
    using namespace std;
    int n,m,a[N];
    
    template<typename T> void read(T &x) {
        char ch=getchar(); T f=1; x=0;
        while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
        if(ch=='-') f=-1,ch=getchar();
        for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    }
    
    int ecnt,fir[N<<1],nxt[N<<2],to[N<<2],val[N<<2];
    void add(int u,int v,int w) {
        nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v; val[ecnt]=w;
        nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u; val[ecnt]=w;
    }
    
    int top,cnt,bvs[N<<1];
    #define pr pair
    #define MP make_pair
    #define se second
    #define fi first
    vector<pr>son[N],son2[N<<1];
    void prebuild(int x,int fa) {
        int up=son[x].size();
        For(i,0,up-1) if(son[x][i].fi!=fa) {
            son2[x].push_back(son[x][i]);
            prebuild(son[x][i].fi,x);
        }
    }
    
    void rebuild(int x) {
        int up=son2[x].size();
        bvs[x]=1;
        if(up<=2) {
            For(i,0,up-1) add(x,son2[x][i].fi,son2[x][i].se);
        }	
        else if(up==3) {
            son2[++cnt].push_back(son2[x][0]);
            son2[cnt].push_back(son2[x][1]);
            add(x,cnt,0); add(x,son2[x][2].fi,son2[x][2].se);
        }
        else {
            For(i,0,up-1) {
                if(i&1) son2[cnt+1].push_back(son2[x][i]);
                else son2[cnt+2].push_back(son2[x][i]);
            }
            add(x,++cnt,0); add(x,++cnt,0);
        }
        for(int i=fir[x];i;i=nxt[i]) if(!bvs[to[i]])
            rebuild(to[i]);
    }
    
    int RT,sz[N<<1],msz[N<<1],vis[N<<1];
    void get_root(int x,int fa,int tot) {
        sz[x]=msz[x]=1;
        for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa&&!vis[to[i]]) {
            get_root(to[i],x,tot);
            sz[x]+=sz[to[i]];
            msz[x]=max(msz[x],sz[to[i]]);
        }
        msz[x]=max(msz[x],tot-sz[x]);
        if(!RT||msz[RT]>msz[x]) RT=x;
    }
    
    vector<LL>ds[N<<1];
    void dfs(int x,int fa,LL R) {
        ds[x].push_back(R);
        for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa&&!vis[to[i]]) 
            dfs(to[i],x,R+val[i]);
    }
    
    int totnd,rt[N],tr[N*60],ch[N*60][3];
    LL sum[N*60][3];
    
    LL dis[N<<1][20];
    int dfk,dfn[N<<1],low[N<<1],tR[N<<1];
    int in(int a,int b) { return dfn[a]>=dfn[b]&&dfn[a]<=low[b]; }
    
    void build(int x,int tot) {
        tr[x]=x;
        vis[x]=1;
        dfs(x,0,0);
        dfn[x]=low[x]=++dfk;
        int up=ds[x].size()-1,xson=0;
        For(i,0,18) if(up>=0) 
            dis[x][i]=ds[x][up--];    
        for(int i=fir[x];i;i=nxt[i]) if(!vis[to[i]]) {
            int lsz=sz[to[i]]>sz[x]?tot-sz[x]:sz[to[i]];
            RT=0; get_root(to[i],x,lsz); 
            ch[x][xson++]=RT; tR[RT]=tR[x]+1; 
            build(RT,lsz); low[x]=max(low[x],low[RT]);
        }
    }
    
    void upd(int &x,int last,int R,int nd) {
        x=++totnd;
        tr[x]=tr[last];
        For(i,0,2) ch[x][i]=ch[last][i],sum[x][i]=sum[last][i];
        sum[x][0]++;
        sum[x][1]+=dis[nd][tR[nd]-R];
        if(R) sum[x][2]+=dis[nd][tR[nd]-R+1];
        if(tr[x]==nd) return;
        For(i,0,2) if(ch[x][i]&&in(nd,tr[ch[x][i]]))
            upd(ch[x][i],ch[last][i],R+1,nd);
    }
    
    LL Qrs;
    void preQ() { Qrs=0; }
    void qry(int x,int R,int nd) {
        Qrs+=(sum[x][1]+sum[x][0]*dis[nd][tR[nd]-R]);
        if(R) Qrs-=(sum[x][2]+sum[x][0]*dis[nd][tR[nd]-R+1]);
        if(tr[x]==nd) return;
        For(i,0,2) if(ch[x][i]&&in(nd,tr[ch[x][i]]))
            qry(ch[x][i],R+1,nd);
    }
    
    LL lastans;
    void Qry(int ql,int qr,int x) {
        LL rs=0;
      	preQ(); qry(rt[qr],0,x); rs+=Qrs;
      	preQ(); if(ql-1) qry(rt[ql-1],0,x); rs-=Qrs;
        printf("%I64d
    "
    ,rs); lastans=rs%(1<<30); } int main() { //freopen("std.in","r",stdin); //freopen("WA.out","w",stdout); read(n); read(m); For(i,1,n) read(a[i]); For(i,2,n) { int u,v,w; read(u); read(v); read(w); son[u].push_back(MP(v,w)); son[v].push_back(MP(u,w)); } cnt=n; prebuild(1,0); rebuild(1); RT=0; get_root(1,0,cnt); rt[0]=RT; build(RT,cnt); totnd=cnt; For(i,1,n) upd(rt[i],rt[i-1],0,a[i]); int qc=0; For(i,1,m) { int op,x,l,r; read(op); if(op==1) { read(l); read(r); read(x); l^=lastans; r^=lastans; x^=lastans; Qry(l,r,x); } else { read(x); x^=lastans; upd(rt[x],rt[x-1],0,a[x+1]); swap(a[x],a[x+1]); } } Formylove; }

    좋은 웹페이지 즐겨찾기