csp-s analog 45,50 weight, vegetables, Union

Questions surface: https://www.cnblogs.com/Juve/articles/11574985.html

vegetables:

Commentary and questions related to the four-dimensional partial order, but it did not see the changes, you can water over Mo team

Everolimus a two-team, four-defined pointer, respectively, represent the coordinates of the upper left and lower right corner

Then the team moved on Mo simulated sequence

while(u<ask[i].x) del_h(u++);
while(u>ask[i].x) add_h(--u);
while(d<ask[i].p) add_h(++d);
while(d>ask[i].p) del_h(d--);
while(l<ask[i].y) del_l(l++);
while(l>ask[i].y) add_l(--l);
while(r<ask[i].q) add_l(++r);
while(r>ask[i].q) del_l(r--);

u is up, d is down, l is left, r is right, then the answer to statistics

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define int long long
#define re register
using namespace std;
const int MAXN=205;
int n,m,q,a[MAXN][MAXN],cnt=0,tot=0,ans[100005];
int b[MAXN*MAXN],num[MAXN*MAXN],u=1,d=0,l=1,r=0;
struct node{
	int x,y,p,q,id;
	friend bool operator < (node a,node b){
		return (a.x==b.x?(a.y==b.y?(a.p==b.p?(a.q<b.q):a.p<b.p):a.y<b.y):a.x<b.x);
	}
}ask[100005];
void del_h(int ha){
	for(int i=l;i<=r;++i) --num[a[ha][i]];
}
void add_h(int ha){
	for(int i=l;i<=r;++i) ++num[a[ha][i]];
}
void del_l(int li){
	for(int i=u;i<=d;++i) --num[a[i][li]];
}
void add_l(int li){
	for(int i=u;i<=d;++i) ++num[a[i][li]];
}
signed main(){
	//freopen("test.in","r",stdin);
	//freopen("vio.out","w",stdout);
	scanf("%lld%lld%lld",&n,&m,&q);
	for(re int i=1;i<=n;++i){
		for(re int j=1;j<=m;++j){
			scanf("%lld",&a[i][j]);
			b[++tot]=a[i][j];
		}
	}
	sort(b+1,b+tot+1);
	cnt=unique(b+1,b+tot+1)-b-1;
	for(re int i=1;i<=n;++i){
		for(re int j=1;j<=m;++j)
			a[i][j]=lower_bound(b+1,b+cnt+1,a[i][j])-b;
	}
	for(int i=1;i<=q;++i){
		scanf("%lld%lld%lld%lld",&ask[i].x,&ask[i].y,&ask[i].p,&ask[i].q);
		ask[i].id=i;
	}
	sort(ask+1,ask+q+1);
	for(int i=1;i<=q;++i){
		while(u<ask[i].x) del_h(u++);
		while(u>ask[i].x) add_h(--u);
		while(d<ask[i].p) add_h(++d);
		while(d>ask[i].p) del_h(d--);
		while(l<ask[i].y) del_l(l++);
		while(l>ask[i].y) add_l(--l);
		while(r<ask[i].q) add_l(++r);
		while(r>ask[i].q) del_l(r--);
		for(int j=1;j<=cnt;++j){
			ans[ask[i].id]+=num[j]*num[j];
		}
	}
	for(int i=1;i<=q;++i){
		printf("%lld\n",ans[i]);
	}
	return 0;
}

alliance:

This question is related to the diameter of the tree and

To obtain the original diameter of the tree, and then (the edge on the optimum constant diameter segment) in diameter enumerate disconnected

Diameter set off after two Unicom blocks are $ l_1 $, $ l_2 $, then the answer to the first question is,

$max(l_1,l_2,\lceil\frac{l_1}{2}\rceil+\lceil\frac{l_2}{2}\rceil+1)$

I asked the second question first came out is not a problem

Then the third question, we just find a side to be off, the midpoint of the diameter of the connection points is two blocks Unicom

He played four dfs and four bfs, code length 4.0k, if I practice a lot of trouble?

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define re register
using namespace std;
const int MAXN=3e5+5;
int n,fmx=0,smx=0,ans=0x3f3f3f3f;
int to[MAXN<<1],nxt[MAXN<<1],pre[MAXN],cnt=1,id[MAXN<<1],fr[MAXN<<1];
inline void add(re int u,re int v,re int rk){
	++cnt,to[cnt]=v,nxt[cnt]=pre[u],pre[u]=cnt,id[cnt]=rk,fr[cnt]=u;
}
int dp[2][MAXN];
int DFs(int x,int fa,int flag){
	int maxx=0;
	dp[flag][x]=0;
	for(int i=pre[x];i;i=nxt[i]){
		int y=to[i];
		if(y==fa) continue;
		int p=DFs(y,x,flag);
		dp[flag][x]=max(dp[flag][x],max(maxx+p,dp[flag][y]));
		maxx=max(maxx,p);
	}
	return maxx+1;
}
int d[MAXN],p[MAXN],qd,zd,dis[MAXN];
int stac[MAXN],topc=0;
int bfs(int s){
	topc=0;
	memset(d,0x3f,sizeof(d));
	d[s]=0;
	p[s]=0;
	queue<int>q;
	q.push(s);
	while(!q.empty()){
		int x=q.front();
		q.pop();
		for(int i=pre[x];i;i=nxt[i]){
			int y=to[i];
			if(d[y]==0x3f3f3f3f){
				d[y]=d[x]+1;
				p[y]=i;
				q.push(y);
			}
		}
	}
	int y=1;
	for(int i=1;i<=n;++i){
		if(dis[i]==0x3f3f3f3f) continue;
		if(d[i]>d[y]) y=i,topc=0;
		//if(d[i]==d[y]) stac[++topc]=i;
	}
	return y;
}
int BFS(int s,int ed){
	if(s==ed) return 0;
	memset(dis,0x3f,sizeof(dis));
	dis[s]=0;
	queue<int>q;
	q.push(s);
	while(!q.empty()){
		int x=q.front();
		q.pop();
		for(int i=pre[x];i;i=nxt[i]){
			int y=to[i];
			if(y==ed) continue;
			if(dis[y]==0x3f3f3f3f){
				dis[y]=dis[x]+1;
				q.push(y);
			}
		}
	}
	int res=0;
	for(int i=1;i<=n;++i){
		if(dis[i]==0x3f3f3f3f) continue;
		res=max(res,dis[i]);
	}
	return res;
}
int sta[MAXN],top=0;
/*void work(int x){
	if(x==0) return ;
	int i=p[x];
	int p=BFS(zd,fr[i]),q=BFS(qd,x);
	//cout<<x<<' '<<fr[i]<<' '<<p<<' '<<q<<' '<<' '<<(p+1)/2+(q+1)/2+1<<' '<<i<<endl;
	int t=max(max(p,q),(p+1)/2+(q+1)/2+1);
	if(ans==t) sta[++top]=i;
	if(ans>t) top=0,sta[++top]=i;
	ans=min(ans,t);
	work(fr[i]);
}*/
void work(int x){
	if(x==0) return ;
	int i=p[x];
	int p=dp[1][fr[i]],q=dp[0][x];
	//cout<<x<<' '<<fr[i]<<' '<<p<<' '<<q<<' '<<' '<<(p+1)/2+(q+1)/2+1<<' '<<i<<endl;
	int t=max(max(p,q),(p+1)/2+(q+1)/2+1);
	if(ans==t) sta[++top]=i;
	if(ans>t) top=0,sta[++top]=i;
	ans=min(ans,t);
	work(fr[i]);
}
int Bfs(int s){
	memset(d,0x3f,sizeof(d));
	d[s]=0;
	p[s]=0;
	queue<int>q;
	q.push(s);
	while(!q.empty()){
		int x=q.front();
		q.pop();
		for(int i=pre[x];i;i=nxt[i]){
			int y=to[i];
			if(d[y]==0x3f3f3f3f){
				d[y]=d[x]+1;
				p[y]=i;
				q.push(y);
			}
		}
	}
	int y=1;
	for(int i=1;i<=n;++i){
		if(dis[i]==0x3f3f3f3f) continue;
		if(d[i]>d[y]) y=i;
	}
	return y;
}
int edge,frr,too,len;
int BFs(int s,int ed){
	if(s==ed) return 0;
	memset(dis,0x3f,sizeof(dis));
	dis[s]=0;
	queue<int>q;
	q.push(s);
	while(!q.empty()){
		int x=q.front();
		q.pop();
		for(int i=pre[x];i;i=nxt[i]){
			int y=to[i];
			if(y==ed) continue;
			if(dis[y]==0x3f3f3f3f){
				dis[y]=dis[x]+1;
				p[y]=i;
				q.push(y);
			}
		}
	}
	int y=s;
	for(int i=1;i<=n;++i){
		if(dis[i]==0x3f3f3f3f) continue;
		if(dis[i]>dis[y]) y=i;
	}
	return y;
}
int ans1=0,ans2=0;
void dfs(int x,int l){
	if(x==0) return ;
	if(l==len){
		ans1=x;
		return ;
	}
	int i=p[x];
	dfs(fr[i],l+1);
}
void DFS(int x,int l){
	if(x==0) return ;
	if(l==len){
		ans2=x;
		return ;
	}
	int i=p[x];
	DFS(fr[i],l+1);
}
signed main(){
	//freopen("dt.in","r",stdin);
	//freopen("my.out","w",stdout);
	scanf("%d",&n);
	for(int i=1,u,v;i<n;++i){
		scanf("%d%d",&u,&v);
		add(u,v,i),add(v,u,i);
	}
	qd=bfs(1);
	zd=bfs(qd);
	DFs(qd,0,0);
	DFs(zd,0,1);
	work(zd);
	printf("%d\n",ans);
	sort(sta+1,sta+top+1);
	top=unique(sta+1,sta+top+1)-sta-1;
	printf("%d ",top);
	for(int i=1;i<=top;++i){
		printf("%d ",id[sta[i]]);
	}
	puts("");
	edge=sta[top];
	frr=fr[edge],too=to[edge];
	qd=BFs(frr,too);
	zd=BFs(qd,too);
	len=dis[zd]/2;
	//cout<<len<<endl;
	dfs(zd,0);
	qd=BFs(too,frr);
	zd=BFs(qd,frr);
	len=dis[zd]/2;
	DFS(zd,0);
	printf("%d %d %d %d\n",frr,too,ans1,ans2);
	return 0;
}

weight:

Ran kruskal first minimal spanning tree, and then discuss the side of the tree and for non-tree edges

For a non-tree edge, at least we want to adjust its weights tree paths corresponding to the two endpoints of edge weights can -1 maximum,

Otherwise, we certainly can not vote for this edge. Obviously, we adjust to such a large enough.

For a tree edge, our concern is obviously two simple paths corresponding to those endpoints through the side edges of this tree,

We most likely choice is the right side of those in the smallest edge weight value of -1, (or we can choose the smallest side piece of the election without this side of the tree),

And if we put this tree right side edge adjusted to that value, it certainly will be in the minimum spanning tree.

Then we cross the minimum spanning tree operation is implemented

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=1e6+5;
const int inf=0x3f3f3f3f;
int n,m,xkl,ans[MAXN];
struct EDGE{
	int fr,to,nxt,val,id;
	bool flag;
	friend bool operator < (EDGE a,EDGE b){
		return a.val<b.val;
	}
}ed[MAXN];
int cnt=0,pre[MAXN],head[MAXN],tot=0;
void add(int u,int v,int w,int id){
	ed[++cnt]=(EDGE){u,v,pre[u],w,id,0};
	pre[u]=cnt;
}
struct node{
	int fr,to,nxt,val,id;
}e[MAXN];
void ADD(int u,int v,int val,int id){
	e[++tot]=(node){u,v,head[u],val,id};
	head[u]=tot;
}
int fa[MAXN];
int find(int x){
	return fa[x]=(fa[x]==x?x:find(fa[x]));
}
void kruskal(){
	for(int i=1;i<=n;++i) fa[i]=i;
	sort(ed+1,ed+cnt+1);
	int sum=0;
	for(int i=1;i<=cnt;++i){
		int x=find(ed[i].fr),y=find(ed[i].to);
		if(x!=y){
			fa[x]=y;
			++sum;
			ed[i].flag=1;
			ADD(ed[i].fr,ed[i].to,ed[i].val,ed[i].id);
			ADD(ed[i].to,ed[i].fr,ed[i].val,ed[i].id);
			if(sum==n-1) break;
		}
	}
}
int deep[MAXN],size[MAXN],son[MAXN],val[MAXN],rcd[MAXN];
void dfs(int x,int father){
	size[x]=1;
    for(int i=head[x];i;i=e[i].nxt){
        int y=e[i].to;
        if(y==father) continue;
        deep[y]=deep[x]+1;
        fa[y]=x;
        val[y]=e[i].val;
        rcd[y]=e[i].id;
        dfs(y,x);
        size[x]+=size[y];
        if(size[y]>size[son[x]]) son[x]=y;
    }
}
int top[MAXN],id[MAXN],rk[MAXN],dfs_order=0;
void DFS(int x,int chain){
	top[x]=chain;
    id[x]=++dfs_order;
    rk[dfs_order]=x;
    if(son[x]) DFS(son[x],chain);
    for(int i=head[x];i;i=e[i].nxt){
        int y=e[i].to;
        if(y==fa[x]||y==son[x]) continue;
        DFS(y,y);
    }
}
struct TREE{
	int l,r,laz,mx,mn;
}tr[MAXN<<2];
void build(int k,int l,int r){
	tr[k].l=l,tr[k].r=r,tr[k].laz=inf;
	if(l==r){
		tr[k].mn=inf;
		tr[k].mx=val[rk[l]];
		return ;
	}
	int mid=(l+r)>>1;
	build(k<<1,l,mid),build(k<<1|1,mid+1,r);
	tr[k].mx=max(tr[k<<1].mx,tr[k<<1|1].mx);
}
void down(int k){
    tr[k<<1].laz=min(tr[k<<1].laz,tr[k].laz);
    tr[k<<1|1].laz=min(tr[k<<1|1].laz,tr[k].laz);
    tr[k<<1].mn=min(tr[k].laz,tr[k<<1].mn);
    tr[k<<1|1].mn=min(tr[k].laz,tr[k<<1|1].mn);
    tr[k].laz=inf;
}
int query(int k,int opl,you OPR) { 
	you're tr = [k] .The, r = tr [k] .r;
        return tr[k].mx;
int query_path(int x,int y) { 
	int no = 0;
    while(top[x]!=top[y]){
        if(deep[top[x]]<deep[top[y]]) swap(x,y);
        res=max(res,query(1,id[top[x]],id[x]));
        x=fa[top[x]];
    }
    if(deep[x]>deep[y]) swap(x,y);
    res=max(res,query(1,id[x]+1,id[y]));
    return res;
}
void update_path(int x,int y,int val){
	while(top[x]!=top[y]){
        if(deep[top[x]]<deep[top[y]]) swap(x,y);
        update(1,id[top[x]],id[x],val);
        x=fa[top[x]];
    }
    if(deep[x]>deep[y]) swap(x,y);
    update(1,id[x]+1,id[y],val);
}
void ask_ans(int k){
	if(tr[k].l==tr[k].r){
        ans[rcd[rk[tr[k].l]]]=tr[k].mn-1;
        if(ans[rcd[rk[tr[k].l]]]==inf-1){
            ans[rcd[rk[tr[k].l]]]=-1;
        }
        return ;
    }
	if(tr[k].laz!=inf) down(k);
	ask_ans(k<<1),ask_ans(k<<1|1);
}
signed main(){
	//freopen("test.in","r",stdin);
	//freopen("vio.out","w",stdout);
	scanf("%d%d%d",&n,&m,&xkl);
	for(int i=1,u,v,w;i<=m;++i){
		scanf("%d%d%d",&u,&v,&w);
		add(u,v,w,i);
		//add(v,u,w,i);
	}
	kruskal();
	memset(fa,0,sizeof(fa));
	deep[1]=1;
	dfs(1,0);DFS(1,1);
	build(1,1,n);
	for(int i=1;i<=cnt;++i){
		if(ed[i].flag==0){
			//cout<<ed[i].id<<endl;
			ans[ed[i].id]=query_path(ed[i].fr,ed[i].to)-1;
			//cout<<ans[ed[i].id]<<endl;
			//cout<<ed[i].fr<<' '<<ed[i].to<<endl;
			update_path(ed[i].fr,ed[i].to,ed[i].val);
		}
	}
	ask_ans(1);
	for(int i=1;i<=m;++i)
		printf("%d ",ans[i]);
	puts("");
	return 0;
}

 

Guess you like

Origin www.cnblogs.com/Juve/p/11576165.html