传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2870
看完就想到点分治了
可是用传统的点分治合并两条子树的链的时候很蛋疼……
于是我们换个方式
找到重心后把子树分成两堆,统计过根且起始结束位置在两个不同的堆里的答案
递归两堆子树
这种思想很早就有了 http://hi.baidu.com/345585690/item/fc3d0dd3167c28896cce3f09 http://blog.sina.com.cn/s/blog_76f6777d0101imnn.html
而且也不是很难写
如果把分治过程记录下来就可以做到动态修改询问,不过好像没人给这种数据结构起名字(或者我太弱了不知道)……
我就给它起名叫点分树了……
边分加虚点,括号序列什么的都太神了不会
好像树上点/链修改,整体/子树 路径查询的题不多……(QTREE有几个,wc,zjoi也有)
似乎可以有一大波新题诞生(又要被D了233)?
不过说起来这道题是静态的我在这扯什么蛋……
马上就去写1095
Code:
#include
using namespace std;
const int maxn=50010;
int getint(){
int res=0;char c=getchar();
while(!isdigit(c))c=getchar();
while(isdigit(c))res=res*10+c-'0',c=getchar();
return res;
}
vectorG[maxn];
int n,f[maxn],siz[maxn],w[maxn],d[maxn],root,dep[maxn];
int cant[maxn];
long long ans;
void makert(int u,int All,int fa,int &root){
siz[u]=1;f[u]=0;
for(int i=0,v;if[u])root=u;
}
int dsize,dsize2,tsize;
pair data[maxn],data2[maxn];
pair tmp[maxn];
void dfs(int u,int fa){
data[++dsize]=make_pair(d[u],dep[u]);
for(int i=0,v;i=(All+1)/2||used+1==can)break;
}dsize=0;dep[u]=0;d[u]=w[u];dfs(u,u);dsize2=dsize;
copy(data+1,data+1+dsize,data2+1);
for(int i=0,v;i=1;i--)
if(data[i].second>maxy)tmp[++tsize]=data[i],maxy=data[i].second;
copy(tmp+1,tmp+1+tsize,data+1);dsize=tsize;maxy=-1;tsize=0;
for(int i=dsize2;i>=1;i--)
if(data2[i].second>maxy)tmp[++tsize]=data2[i],maxy=data2[i].second;
copy(tmp+1,tmp+1+tsize,data2+1);dsize2=tsize;
sort(data+1,data+1+dsize);
sort(data2+1,data2+1+dsize2);
for(int i=1;i<=dsize;i++){
ans=max(ans,(long long)data[i].first*(data[i].second+1));
pair *x=lower_bound(data2+1,data2+1+dsize2,make_pair(data[i].first,-1));
if(x==data2+1+dsize2)continue;
ans=max(ans,(long long)(data[i].second+x->second+1)*data[i].first);
}
for(int i=1;i<=dsize2;i++){
ans=max(ans,(long long)data2[i].first*(data2[i].second+1));
pair *x=lower_bound(data+1,data+1+dsize,make_pair(data2[i].first,-1));
if(x==data+1+dsize)continue;
ans=max(ans,(long long)(data2[i].second+x->second+1)*data2[i].first);
}
if(sum+1>2)
solve(u,sum+1);
for(int i=0,v;i2)
solve(u,All-sum);
for(int i=0;i