MnZn刚学二分+主席树求卡常
查看原帖
MnZn刚学二分+主席树求卡常
756684
寄风孤影楼主2024/12/3 20:49

RT,84分,在链的那几个部分被卡了。

代码如下:

#include<bits/stdc++.h>
using namespace std;
#define int long long   
int a [  1000005   ]   ,  ans[1000005];  
int dfn[1000005],cc,n,q,st[1000005][19],ss[1000005][19] , dep[1000005];
vector<int>e[1000005];
inline int Min(int x,int y){return (dfn[x]<dfn[y]?x:y);}
inline void dfs(int u,int fa=0){st[dfn[u]=++cc][0]=fa;dep[u] = dep[fa]+1;for(auto v:e[u])if(v!=fa)dfs(v,u);}
inline void stt(){int up=__lg(n);for(int i=1;i<=up;i++)for(int j=1;j<=n;j++)st[j][i]=Min(st[j][i-1],st[j+(1<<i-1)][i-1]);}
inline int lca(int u,int v){if(u==v)return u;if((u=dfn[u])>(v=dfn[v]))(u^=v^=u^=v);
int l=__lg(v-(u++));return Min(st[u][l],st[v-(1<<l)+1][l]);}
inline int qry(int l ,  int r){
    int pos = __lg(r - l + 1); 
    return max(ss[l][pos] , ss[r - (1 << pos) + 1][pos]);
}
const int N = 5e5 + 5;
namespace seg{
	struct nnd{
		int lx , rx , s , ans;
		nnd(){
			lx=rx=s=ans=INT_MIN;
		}
		nnd operator +(const nnd &bb) const{
			nnd a = (*this) , b = bb , c;
			c.lx = a.lx , c.rx = b.rx;
			c.lx = max(c.lx , a.s + b.lx);
			c.rx = max(c.rx , b.s + a.rx);
			c.s = a.s + b.s;
			c.ans = max(a.rx + b.lx , max(a.ans , b.ans));
			return c;
		}
	};
	struct node{
		int ls , rs;
		nnd x;
		node(){
			x=nnd();
			ls=rs=0;
		}
	} d[N*21];
	int rt[N];
	inline void pushup(int p){
		d[p].x = d[d[p].ls].x + d[d[p].rs].x;
	}
	int tot;	
	inline void insert(int &x , int  p ,  int id , int l , int r){
		x=(++tot);
		d[x] = d[p];
		if(l == r){
			d[x].x.s=d[x].x.lx=d[x].x.rx=d[x].x.ans=1;
			return ;
		}
		int mid = l + r >> 1;
		if(id <= mid) insert(d[x].ls , d[p].ls , id , l , mid);
		else insert(d[x].rs , d[p].rs , id , mid + 1 , r);
		pushup(x);
	}
	inline nnd qry(int p , int l , int r,  int s , int t){
		if(!p) return d[p].x;
		if(l <= s && t <= r) return d[p].x;
		int mid = s + t >> 1;
		if(r <= mid) return qry(d[p].ls , l , r , s , mid);
		if(mid < l) return qry(d[p].rs , l , r , mid + 1 , t);
		return qry(d[p].ls , l , r , s , mid) + qry(d[p].rs , l , r , mid + 1 , t);
	}
};
using namespace seg;
vector<int>dd[N];
signed main(){
	// freopen("query2.in" , "r" , stdin);
	// freopen("query.out" , "w" , stdout);
	ios::sync_with_stdio(0);
	cin.tie(0) , cout.tie(0);
	cin>>n;
	bool fg = 1;
	for(int i=1,u,v;i<n;i++)cin>>u>>v,fg&=(u==i&&v==i+1) , e[u].push_back(v),e[v].push_back(u);
	dfs(1),stt();
	for(int  i = 1; i <= n  ; i ++  )  {
		ss[i][0] = dep[i];
	}
    int dw = __lg(n);
    for(int i = 1;i <= dw;i++){
        for(int j = 1;j + (1 << i) - 1 <= n;j++){
            ss[j][i] = max(ss[j][i - 1] , ss[j + (1 << (i - 1))][i - 1]);
        }
    }
    for(int i = 1;i < n;i++) a[i]=dep[lca(i,i+1)];
    	// cout<<'\n';
	for(int i = 1;i < n;i++){
		dd[a[i]].push_back(i);
	}
	for(int i = n;i;i--){
		rt[i]=rt[i+1];
		// cerr<<"DW: "<<i<<' '<<rt[i]<<'\n';
		for(auto v:dd[i]){
			// cerr<<"DD "<<i<<' '<<v<<'\n';
			insert(rt[i] , rt[i] , v , 1 , n);
		}
	}
	cin >> q;
	int l , r , k;
	while(q--){
		cin >> l >> r >> k;
		// if(fg){
		// 	cout<<r-k+1<<'\n';
		// 	continue;
		// }
		if(k==1){
			cout<<qry(l,r)<<'\n';
			continue;
		}
		// continue;
		r-- , k--;
		int ll = 1 , rr = n , res = -1;
		while(ll <= rr){
			// cerr
			int mid = ll+rr>>1;
			if(d[rt[mid]].x.ans >= k){
				if(qry(rt[mid] , l , r , 1 , n).ans >= k){
					ll = mid + 1;
					res = mid;
				}
				else{
					rr = mid - 1;
				}
			}
			else{
				rr = mid - 1;
			}
		}
		cout<<res<<'\n';
	}
	cerr<<clock()*1.0/CLOCKS_PER_SEC<<'\n';
}
2024/12/3 20:49
加载中...