zoukankan      html  css  js  c++  java
  • 7.18 NOI模拟赛 因懒无名 线段树分治 线段树维护直径

    LINK:因懒无名

    avatar
    avatar

    20分显然有(ncdot 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
    ",x)
    #define putl(x) printf("%lld
    ",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>
  • 相关阅读:
    uva 10491 Cows and Cars
    uva 10910 Marks Distribution
    uva 11029 Leading and Trailing
    手算整数的平方根
    uva 10375 Choose and divide
    uva 10056 What is the Probability?
    uva 11027 Palindromic Permutation
    uva 10023 Square root
    Ural(Timus) 1081. Binary Lexicographic Sequence
    扩展欧几里得(求解线性方程)
  • 原文地址:https://www.cnblogs.com/chdy/p/13336489.html
Copyright © 2011-2022 走看看