1. 程式人生 > 實用技巧 >7.18 NOI模擬賽 因懶無名 線段樹分治 線段樹維護直徑

7.18 NOI模擬賽 因懶無名 線段樹分治 線段樹維護直徑

LINK:因懶無名


20分顯然有\(n\cdot q\)的暴力。

還有20分 每次只詢問一種顏色的直徑不過帶修改。

容易想到利用線段樹維護直徑就可以解決了。

當然也可以進行線段樹分治 每種顏色存一下直徑的端點即可。

考慮100分。

考慮到直徑兩個端點有區間可加性 所以直接外面套一個線段樹維護區間端點即可。

修改採用上述做法兩種均可。然後就做完了.

code
//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<ctime>
#include<cctype>
#include<queue>
#include<deque>
#include<stack>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<queue>
#include<deque>
#include<stack>
#include<vector>
#include<algorithm>
#include<utility>
#include<bitset>
#include<set>
#include<map>
#define ll long long
#define db double
#define INF 100001
#define ldb long double
#define pb push_back
#define put_(x) printf("%d ",x);
#define get(x) x=read()
#define gt(x) scanf("%d",&x)
#define gi(x) scanf("%lf",&x)
#define put(x) printf("%d\n",x)
#define putl(x) printf("%lld\n",x)
#define rep(p,n,i) for(RE int i=p;i<=n;++i)
#define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define fep(n,p,i) for(RE int i=n;i>=p;--i)
#define vep(p,n,i) for(RE int i=p;i<n;++i)
#define pii pair<int,int>
#define mk make_pair
#define RE register
#define P 1000000007ll
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define uint unsigned long long
#define ui unsigned
#define EPS 1e-4
#define sq sqrt
#define S second
#define F first
#define mod 1000000007
#define l(p) t[p].l
#define r(p) t[p].r
#define L(p) t[p].L
#define R(p) t[p].R
#define mx(p) t[p].mx
using namespace std;
char *fs,*ft,buf[1<<15];
inline char gc()
{
	return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
}
inline int read()
{
	RE int x=0,f=1;RE char ch=gc();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=gc();}
	return x*f;

}
const int MAXN=100010;
int n,m,len,Q,maxx,id,cnt,vv,ww,rt;
int c[MAXN],root[MAXN],d[MAXN];
int f[MAXN<<1][20],Log[MAXN<<1],dfn[MAXN],g[MAXN],pos[MAXN];
int lin[MAXN],nex[MAXN<<1],ver[MAXN<<1];
vector<int>w;
inline void add(int x,int y)
{
	ver[++len]=y;
	nex[len]=lin[x];
	lin[x]=len;
}
inline void dfs(int x,int fa)
{
	f[++cnt][0]=x;dfn[x]=cnt;d[x]=d[fa]+1;
	//f為ST表元素 ->dfn->cnt
	g[++id]=x;pos[id]=x;//g為dfs序->pos->id;
	go(x)if(tn!=fa)
	{
		dfs(tn,x);
		f[++cnt][0]=x;
	}
}
inline int cmp(int x,int y){return d[x]>d[y]?y:x;}
inline int LCA(int x,int y)
{
	x=dfn[x];y=dfn[y];
	if(x>y)swap(x,y);
	int z=Log[y-x+1];
	return cmp(f[x][z],f[y-(1<<z)+1][z]);
}
inline int dist(int x,int y)
{
	if(!x||!y)return 0;
	int lca=LCA(x,y);
	return d[x]+d[y]-2*d[lca];
}
struct wy
{
	int l,r,L,R;int mx;
	inline wy friend operator +(wy a,wy b)
	{
		if(!b.L&&!b.R)return a;
		if(!a.L&&!a.R)return b;
		wy c;
		if(a.mx>b.mx)c=a;else c=b;
		if((ww=dist(a.L,b.L))>c.mx)c.L=a.L,c.R=b.L,c.mx=ww;
		if((ww=dist(a.L,b.R))>c.mx)c.L=a.L,c.R=b.R,c.mx=ww;
		if((ww=dist(a.R,b.L))>c.mx)c.L=a.R,c.R=b.L,c.mx=ww;
		if((ww=dist(a.R,b.R))>c.mx)c.L=a.R,c.R=b.R,c.mx=ww;
		return c;
	}
}t[MAXN*60];
inline void insert(int &p,int l,int r,int x,int w)
{
	if(!p)p=++vv;
	if(l==r)
	{
		L(p)=R(p)=w;
		return;
	}
	int mid=(l+r)>>1;
	if(x<=mid)insert(l(p),l,mid,x,w);
	else insert(r(p),mid+1,r,x,w);
	int wl=l(p),wr=r(p);
	t[p]=t[l(p)]+t[r(p)];
	t[p].l=wl;t[p].r=wr;
}
inline void build(int &p,int l,int r)
{
	p=++vv;
	if(l==r){t[p]=t[root[l]];return;}
	int mid=(l+r)>>1;
	build(l(p),l,mid);
	build(r(p),mid+1,r);
	int wl=l(p),wr=r(p);
	t[p]=t[l(p)]+t[r(p)];
	t[p].l=wl;t[p].r=wr;
}
inline void change(int p,int l,int r,int x)
{
	if(l==r)
	{
		t[p]=t[root[x]];
		return;
	}
	int mid=(l+r)>>1;
	if(x<=mid)change(l(p),l,mid,x);
	else change(r(p),mid+1,r,x);
	int wl=l(p),wr=r(p);
	t[p]=t[l(p)]+t[r(p)];
	t[p].l=wl;t[p].r=wr;
}
inline wy ask(int p,int l,int r,int L,int R)
{
	if(!p)return t[0];
	if(L<=l&&R>=r)return t[p];
	int mid=(l+r)>>1;
	if(R<=mid)return ask(l(p),l,mid,L,R);
	if(L>mid)return ask(r(p),mid+1,r,L,R);
	return ask(l(p),l,mid,L,R)+ask(r(p),mid+1,r,L,R);
}
int main()
{
	freopen("noname.in","r",stdin);
	freopen("noname.out","w",stdout);
	get(n);get(m);get(Q);
	rep(1,n,i)get(c[i]);
	rep(2,n,i)
	{
		int get(x),get(y);
		add(x,y);add(y,x);
	}
	dfs(1,0);
	rep(2,cnt,i)Log[i]=Log[i>>1]+1;
	rep(1,Log[cnt],j)rep(1,cnt-(1<<j)+1,i)f[i][j]=cmp(f[i][j-1],f[i+(1<<j-1)][j-1]);
	rep(1,n,i)insert(root[c[i]],1,n,g[i],i);
	build(rt,1,m);
	rep(1,Q,i)
	{
		int get(op),get(L),get(R);
		if(op==1)
		{
			insert(root[c[L]],1,n,g[L],0);
			change(rt,1,m,c[L]);
			c[L]=R;
			insert(root[c[L]],1,n,g[L],L);
			change(rt,1,m,c[L]);
		}
		else put(ask(rt,1,m,L,R).mx);
	}
	return 0;
}
</details>