萌新刚学OI,线段树求调
查看原帖
萌新刚学OI,线段树求调
663681
C_liar楼主2022/6/7 11:48

昨天写的玄学代码,分数与根的选取有关(?),最高55pts,一般是根节点的答案出错

#include<iostream>
#include<iomanip>
#include<algorithm>
#include<string>
#include<cstring>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<cstdlib>
#define ri register int
#define pii pair<int,int>
typedef long long ll;
const int _=1e5+10;
using namespace std;

int n,m,head[_],tot,logn;
struct Edge{
	int to,nxt;
	Edge(){}
	Edge(int to,int nxt):
		to(to),nxt(nxt){}
}edge[_*2];

inline void add(int u,int v){
	edge[++tot]=Edge(v,head[u]),head[u]=tot;
}

struct SegmentTree{
	int l,r;
	int num,pos;
	#define l(p) t[p].l
	#define r(p) t[p].r
	#define num(p) t[p].num
	#define pos(p) t[p].pos
}t[_*60];

int total;

inline int build(){return ++total;}
/*
inline void update(int p){
	if(num(l(p))<num(r(p))){
		num(p)=num(r(p));pos(p)=pos(r(p));
	}else if(num(l(p))>num(r(p))){
		num(p)=num(l(p));pos(p)=pos(l(p));
	}else{
		pos(p)=min(pos(l(p)),pos(r(p)));
	}
}
*/
inline void update(int p){
	if(l(p)==0){
		num(p)=num(r(p));pos(p)=pos(r(p));
		return;
	}if(r(p)==0){
		num(p)=num(l(p));pos(p)=pos(l(p));
		return;
	}
	if(num(l(p))>=num(r(p)))
		num(p)=num(l(p)),pos(p)=pos(l(p));
	else num(p)=num(r(p)),pos(p)=pos(r(p));
}
int segtree[_];
int f[20][_];
int d[_];
queue<int>q;
bool vis[_];

void bfs(int root){
	q.push(root);d[root]=1;
	segtree[root]=build();
	while(q.size()){
		int u=q.front();q.pop();
		vis[u]=1;
		for(ri i=head[u];i;i=edge[i].nxt){
			int v=edge[i].to;
			if(vis[v]) continue;
			d[v]=d[u]+1;
			f[0][v]=u;
			segtree[v]=build();
			for(ri j=1;j<=logn;j++){
				f[j][v]=f[j-1][f[j-1][v]];
			}
			q.push(v);
		}
	}
}

int lca(int x,int y){
	if(x==y) return x;
	if(d[x]<d[y]) swap(x,y);
	for(ri i=logn;i>=0;i--){
		if(d[f[i][x]]>=d[y]){
			x=f[i][x];
		}
	}
	if(x==y) return x;
	for(ri i=logn;i>=0;i--){
		if(f[i][x]^f[i][y]){
			x=f[i][x];y=f[i][x];
		}
	}
	return f[0][x];
}

void change(int &p,int lf,int rt,int plc,int delta){
	if(p==0) p=build();
	if(lf==rt&&plc==lf){
		num(p)+=delta;
		pos(p)=plc;
		return;
	}
	int mid=(lf+rt)>>1;
	if(plc<=mid&&plc>=lf){
		change(l(p),lf,mid,plc,delta);
	}if(plc>=mid+1&&plc<=rt){
		change(r(p),mid+1,rt,plc,delta);
	}
	update(p);
}

int merges(int p,int _p,int lf,int rt){
	if(!_p) return p;
	if(!p) return _p;
	if(lf==rt){
		num(p)+=num(_p);
		return p;
	}
	int mid=(lf+rt)>>1;
	l(p)=merges(l(p),l(_p),lf,mid);
	r(p)=merges(r(p),r(_p),mid+1,rt);
	update(p);
	return p;
}

int ans[_];

void dfs(int x){
	vis[x]=1;
	for(ri i=head[x];i;i=edge[i].nxt){
		int y=edge[i].to;
		if(vis[y]) continue;
		dfs(y);
		segtree[y]=merges(segtree[x],segtree[y],1,100000);
	}
	if(num(segtree[x])){
		ans[x]=pos(segtree[x]);
	}
}

int root;

int main(){
#ifndef ONLINE_JUDGE
	freopen("4556.txt","w",stdout);
#endif
	cin>>n>>m;
	root=min(n,31);
	logn=log(n)/log(2)+1;
	for(ri i=1;i<=n-1;i++){
		int a,b;scanf("%d%d",&a,&b);
		add(a,b);add(b,a);
	}
	bfs(root);
	for(ri i=1;i<=m;i++){
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		change(segtree[x],1,100000,z,1);
		change(segtree[y],1,100000,z,1);
		int ltt=lca(x,y);
		change(segtree[ltt],1,100000,z,-1);
		change(segtree[f[0][ltt]],1,100000,z,-1);
	}
	memset(vis,0,sizeof(vis));
	dfs(root);
	for(ri i=1;i<=n;i++){
		printf("%d\n",ans[i]);
	}
	return 0;
}

调不出来,今天又写了一份,只有10pts,大红大紫

#include<iostream>
#include<iomanip>
#include<algorithm>
#include<string>
#include<cstring>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<cstdlib>
#define ri register int
#define pii pair<int,int>
typedef long long ll;
//#define debug 1
#ifdef debug
const int _=1e3+10;
#endif
#ifndef debug
const int _=1e5+10;
#endif
using namespace std;

int New();

int n,m,head[_],tot,root,logn;
struct Edge{
	int to,nxt;
	Edge(){}
	Edge(int to,int nxt):
		to(to),nxt(nxt){}
}edge[_*2];
inline void add(int u,int v){
	edge[++tot]=Edge(v,head[u]),head[u]=tot;
}

queue<int>q;
int f[_][20],d[_];
bool vis[_];
int st[_];

void dfs(int x){
	vis[x]=1;
	for(ri i=head[x];i;i=edge[i].nxt){
		int y=edge[i].to;
		if(vis[y]) continue;
		f[y][0]=x;
		d[y]=d[x]+1;
		for(ri j=1;j<=logn;j++){
			f[y][i]=f[f[y][i-1]][i-1];
		}
		dfs(y);
	}
}

int lca(int x,int y){
	if(x==y) return x;
	if(d[x]<d[y]) swap(x,y);
	for(ri i=logn;i>=0;i--){
		if(d[f[x][i]]>=d[y]){
			x=f[x][i];
		}
	}
	if(x==y) return x;
	for(ri i=logn;i>=0;i--){
		if(f[x][i]^f[y][i]){
			x=f[x][i];y=f[y][i];
		}
	}
	return f[x][0];
}

struct SegmentTree{
	int l,r;
	int dat,pos;
	//max_num,sort_of_max_num
	int id;
	#define lc(p) t[p].l
	#define rc(p) t[p].r
	#define data(p) t[p].dat
	#define pos(p) t[p].pos
	#define id(p) t[p].id
}t[_*60];

int total;

inline int New(){
	total++;id(total)=total;
	return total;
}

inline void update(int p){
	if(!lc(p)) lc(p)=New();
	if(!rc(p)) rc(p)=New();
	if(data(lc(p))>=data(rc(p))){
		data(p)=data(lc(p));
		pos(p)=pos(lc(p));
	}else{
		data(p)=data(rc(p));
		pos(p)=pos(rc(p));
	}
}

int cplus(int &p,int l,int r,int position,int delta){
	if(!p) p=New();
	if(l==r){
		pos(p)=position;
		data(p)+=delta;
		return p;
	}
	int mid=(l+r)>>1;
	if(position<=mid)
		lc(p)=cplus(lc(p),l,mid,position,delta);
	if(position>=mid+1)
		rc(p)=cplus(rc(p),mid+1,r,position,delta);
	update(p);
	return p;
}

int merges(int p,int _p,int l,int r){
	if(!p) return _p;
	if(!_p) return p;
	if(l==r){
		data(p)=data(p)+data(_p);
		pos(p)=l;
		return p;
	}
	int mid=(l+r)>>1;
	lc(p)=merges(lc(p),lc(_p),l,mid);
	rc(p)=merges(rc(p),rc(_p),mid+1,r);
	update(p);
	return p;
}

int ans[_];

void dfsans(int x){
	vis[x]=1;
	for(ri i=head[x];i;i=edge[i].nxt){
		int y=edge[i].to;
		if(vis[y]) continue;
		if(d[y]>d[x]){
			dfsans(y);
			st[x]=merges(st[x],st[y],1,100000);
		}
	}
	if(data(st[x])){
		ans[x]=pos(st[x]);
	}
}

int main(){
	cin>>n>>m;
	root=1;
	logn=(int)(log(n)/log(2))+1;
	for(ri i=1;i<=n-1;i++){
		int a,b;scanf("%d%d",&a,&b);
		add(a,b),add(b,a);
	}
	d[root]=1;
	dfs(root);
	for(ri i=1;i<=m;i++){
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		int Lca=lca(x,y);
		st[x]=cplus(st[x],1,100000,z,+1);
		st[y]=cplus(st[y],1,100000,z,+1);
		st[Lca]=cplus(st[Lca],1,100000,z,-1);
		if(f[Lca][0])
			st[f[Lca][0]]=cplus(st[f[Lca][0]],1,100000,z,-1);
	}
	memset(vis,0,sizeof(vis));
	dfsans(root);
	for(ri i=1;i<=n;i++){
		printf("%d\n",ans[i]);
	}
	return 0;
}
2022/6/7 11:48
加载中...