WC 2010 rebuild 重建计划

本文介绍了一种经典的树的分治算法,并通过一个具体题目详细讲解了算法的设计思路及实现过程。文章分析了二分答案的应用场景,阐述了如何进行点分治,并通过实例代码展示了算法的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述就不说了。要题目的请往百度NOI吧。

经典的树的分治,首先,对于答案是分数形式的基本上要使用二分答案,这不是胡扯,详情请见胡伯涛的论文。

那么对于这个题,由于不好估计边分治复杂度(其实边分治是可以过的,好像比点分治要快),对于答案,化成如下形式sigma{e}-ans*s=0,对于一个可行的ans设为val,必然满足sigma{e}-val*s>=0,所以二分。

点分治时,将每个节点到根的路径的权值计算出来,同时记录走过了多少条边。然后按照在每个子树中按照路径走过的边的数目排序,二分答案后验证,合并子树时,第一颗子树在一个数组list中按序保存走过s条边的路径权值最大值,以后的子树中枚举每条路径,利用单调性每次从list中加入一个值用单调队列维护路径的合法性和最优性,在做完一颗子树后这个子树保存的路径与list数组保存的信息合并,作为下一次list使用。

复杂度分析:点分治O(nlogn),每个节点被访问logn+1次,排序O(nlogn)为上限,二分答案验证为O(nlogans),一共做logn次,所以为O(nlognlogans)

Code:(注:不要作为对拍程序,貌似实现有bug)

#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
struct element
{
  int key;
  double val;
} que[100005],lis[2][100005];
const double oo=10000000;
const element ori={0,0};
int vis[100005],sta[100005],next[200005],link[200005],head[100005],sum[100005],f[100005],l[100005],r[100005],dis[100005],a[100005],b[100005],count[100005],w[200005],pre[200005],tot[2],hea=0,tai=0;
bool flag[100005];
int time=0,top=0,tail=0,now=0,e=1,up=0,dn=0,n=0;
double ans=0,limitup=0,limitdn=0,mid=0;
inline void add(int u,int v,int tmpw)
{
  next[++e]=head[u];
  head[u]=e;
  link[e]=v;
  w[e]=tmpw;
  pre[next[e]]=e;
  next[++e]=head[v];
  head[v]=e;
  link[e]=u;
  w[e]=tmpw;
  pre[next[e]]=e;
}
inline void update(double &a,double b)
{
  if (a<b) a=b;
}
inline int cal(int s)
{
  ++time;
  f[s]=0;
  top=0;
  vis[s]=time;
  sta[tail=1]=s;
  int ne=0,y=0,x=0,i=0;
  while (top<tail)
    {
      x=sta[++top];
      for (ne=head[x],y=link[ne];ne;ne=next[ne],y=link[ne])
	if (vis[y]!=time)
	  {
	    vis[y]=time;
	    sta[++tail]=y;
	    f[y]=x;
	  }
      sum[x]=0;
      flag[x]=1;
    }
  if (tail==1) return s;
  for (i=tail,x=sta[i];i>=1;i--,x=sta[i])
    {
      sum[x]++;
      sum[f[x]]+=sum[x];
      if (sum[x]<=tail/2) flag[x]=0;
      if (sum[x]>tail/2) flag[f[x]]=0;
      if (flag[x]) return x;
    }
}
void print(int s)
{
  for (;s;s=f[s])
    printf("%d ",s);
  printf("\n");
}
void dfs(int s)
{
  vis[s]=time;
  int ne=0,x=0;
  l[s]=r[s]=++now;
  a[now]=dis[s];
  b[now]=count[s];
  for (ne=head[s],x=link[ne];ne;ne=next[ne],x=link[ne])
    if (vis[x]!=time)
      {
	f[x]=s;
	dis[x]=dis[s]+w[ne];
	count[x]=count[s]+1;
	if (dn<=count[x] && count[x]<=up) update(ans,(double)(dis[x])/count[x]);
	dfs(x);
	r[s]=r[x];
      }
}
inline void swap(int &a,int &b)
{
  int tmp=a;
  a=b;
  b=tmp;
}
inline void qs(int h,int g)
{
  int l=h,k=g,mid=b[(l+k)/2];
  while (l<=k)
    {
      while (b[l]<mid) l++;
      while (b[k]>mid) k--;
      if (l<=k)
	{
	  swap(b[l],b[k]);
	  swap(a[l],a[k]);
	  l++;
	  k--;
	}
    }
  if (l<g) qs(l,g);
  if (h<k) qs(h,k);
}
inline bool com(int st)
{
  return (dn<=st && st<=up);
}
bool check(double mid,int s)
{
  int ne=head[s],x=link[ne],i=0,j=0,now=0,oth=1;
  double tmpw=0;
  tot[0]=tot[1]=hea=tai=0;
  for (i=l[x];i<=r[x];i++)
    {
      if (b[i]==b[i-1]) update(lis[now][tot[now]].val,a[i]-b[i]*mid);
      else
	{
	  lis[now][++tot[now]].val=a[i]-b[i]*mid;
	  lis[now][tot[now]].key=b[i];
	}
    }
  for (ne=next[ne],x=link[ne];ne;ne=next[ne],x=link[ne])
    {
      hea=tai=0;
      j=tot[now];
      for (i=l[x];i<=r[x];i++)
	{
	  tmpw=a[i]-b[i]*mid;
	  for (;!com(que[hea].key+b[i]) && hea<=tai;hea++);
	  for (;lis[now][j].key+b[i]>up && j>0;j--);
	  for (;com(lis[now][j].key+b[i]) && j>0;j--)
	    {
	      for (;lis[now][j].val>que[tai].val && hea<=tai;tai--);
	      que[++tai]=lis[now][j];
	    }
	  if (hea<=tai && que[hea].val+tmpw>-(1e-5) && com(que[hea].key+b[i])) return 1;
	}
      oth=now;
      now=1-now;
      tot[now]=0;
      i=l[x];j=1;
      lis[oth][tot[oth]+1].key=n+1;
      while (i<=r[x] || j<=tot[oth])
	{
	  for (;i<=r[x] && lis[now][tot[now]].key==b[i];i++)
	    update(lis[now][tot[now]].val,a[i]-b[i]*mid);
	  for (;j<=tot[oth] && lis[now][tot[now]].key==lis[oth][j].key;j++)
	    update(lis[now][tot[now]].val,lis[oth][j].val);
	  if (i<=r[x])
	    if (b[i]<=lis[oth][j].key)
	      lis[now][++tot[now]].key=b[i],
		lis[now][tot[now]].val=a[i]-b[i]*mid,i++;
	    else
	      lis[now][++tot[now]]=lis[oth][j],j++;
	  else
	    if (j<=tot[oth])
	      lis[now][++tot[now]]=lis[oth][j],j++;
	}
    }
  return 0;
}
void getans(int s)
{
  if (tail<dn) return;
  ++time;
  now=0;
  dis[s]=0;count[s]=0;
  f[s]=0;
  limitdn=0;
  dfs(s);
  limitup=1e6;
  int ne=0,x=0,me=0;
  for (ne=head[s],x=link[ne];ne;ne=next[ne],x=link[ne])
    qs(l[x],r[x]);
  while (limitdn+1e-5<limitup)
    {
      mid=(limitup+limitdn)/2;
      if (check(mid,s))
	limitdn=mid;
      else
	limitup=mid;
    }
  update(ans,limitdn);
  for (ne=head[s],x=link[ne],me=ne^1;ne;ne=next[ne],x=link[ne],me=ne^1)
    {
      if (head[x]==me)
	{
	  head[x]=next[me];
	  pre[next[me]]=0;
	}
      else
	{
	  next[pre[me]]=next[me];
	  pre[next[me]]=pre[me];
	}
      pre[me]=0;next[me]=0;link[me]=0;w[me]=0;
      getans(cal(x));
    }
}
int main()
{
  freopen("rebuild.in","r",stdin);
  freopen("rebuild.out","w",stdout);
  scanf("%d%d%d",&n,&dn,&up);
  int i=0,u=0,v=0,tmpw=0;
  for (i=1;i<n;i++)
    {
      scanf("%d%d%d",&u,&v,&tmpw);
      add(u,v,tmpw);
    }
  ans=-oo;
  getans(cal(1));
  printf("%.3f",ans);
  return 0;
}


Im building my cart page. Im using wordpress woocommerce and woodmart theme, and I have a child theme for my woodmart theme. Currently my cart page is empty and im using the default cart page from woodmart theme. I want to fully rebuild it. I have a few requirement here: I want to display a checkbox before the items on the cart page. When the checkbox is clicked, the subtotal on the cart page will change based on the selected items. 在購物車中可以選擇相應的商品下單,based on checkbox(目前實現的是全部商品下單) 4)沒被選擇下單的商品會保留在購物車内,讓用戶下一次再選擇下單 As what i know, the default setting for woocommerce is checkout everything in cart page all at once and remove everything from cart. I think need to overwrite the default setting so that the items can retain inside cart. I have no coding basic, please give me the FULL CODE to be inserted into each required section. the cart.php in my child theme is currently empty, can you give me the full code, i want the layout like normal cart page with 6 column 1)全选商品(checkbox) 2)商品信息 3)商品参数 4)单价 5)数量(可±) 6)金额 7)操作(移除商品) make this as a table with 7 column. After the table, i want a sticky footer that shows select all checkbox, 刪除選中的商品 & 清理購物車 已选商品 (x) 件,共计: RM(x.xx),结算(checkout button) I want my cart page to be 1024px, just like the default settings
最新发布
07-31
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值