7.18 NOI模擬賽 因懶無名 線段樹分治 線段樹維護直徑
阿新 • • 發佈:2020-07-18
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>