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>
  • 相关阅读:
    HBase- 安装单机版HBase
    javascript中的设计模式之模板方法模式
    win 设置自动启动软件
    php高精度加减乘除
    frp实现内网穿透,实现夸服务器访问
    OCM 12c 直考预备知识点
    Oracle 19c New Features : Active Data Guard DML Redirect
    3级搭建类302-Oracle 19c RAC 双节点搭建
    VMWare WorkStation 15.5 配置RAC共享存储节点二无法识别共享磁盘UUID解决办法
    你还在争论 count(*) 与 count(column) 哪个更快?
  • 原文地址:https://www.cnblogs.com/chdy/p/13336489.html
Copyright © 2011-2022 走看看