传送门

Solution

Code 

/*
斯坦纳树;O(n*3^n+kE*2^n) 暂且把O(k*E)当成是spfa的复杂度
15:15~16:20 原题:bzoj_4774
*/
#include<bits/stdc++.h>
#define ll long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
const int MN=105,MM=1005,inf=0x3f3f3f3f;
int n,m,k;
struct edge{int to,w,nex;}e[MM<<1];int hr[MN],en;
inline void ins(int f,int t,int w)
{
e[++en]=(edge){t,w,hr[f]};hr[f]=en;
e[++en]=(edge){f,w,hr[t]};hr[t]=en;
}
std::queue<int> q;
int f[1<<11][MN],g[1<<11],refer[1<<6],ans=inf;
bool inq[MN];
void spfa(int *d)
{
register int u,i;
while(!q.empty())
{
u=q.front();q.pop();inq[u]=false;
for(i=hr[u];i;i=e[i].nex)
if(d[e[i].to]>d[u]+e[i].w)
{
d[e[i].to]=d[u]+e[i].w;
if(!inq[e[i].to]) q.push(e[i].to),inq[e[i].to]=true;
}
}
}
int main()
{
register int i,j,x,y,S,SS,SSS,s;
n=read();m=read();k=read();SS=1<<k;SSS=1<<(k>>1);
while(m--)x=read(),y=read(),ins(x,y,read());
memset(f,0x3f,sizeof f);
for(i=1;i<=k;++i) f[1<<i-1][i]=0;
for(S=1;S<SS;++S)
{
for(i=1;i<=n;++i)
{
for(s=S&(S-1);s;s=(s-1)&S) f[S][i]=min(f[S][i],f[s][i]+f[S^s][i]);
if(f[S][i]<inf) q.push(i);
}
spfa(f[S]);g[S]=inf;
for(i=1;i<=n;++i) g[S]=min(g[S],f[S][i]);
}
for(i=0;i<SSS;++i)
{
s=0;
for(j=0;j<k/2;++j) if(i>>j&1) s|=1<<(j*2);
refer[i]=s|(s<<1);
}
for(S=1;S<SSS;++S)for(s=S&(S-1);s;s=(s-1)&S)
g[refer[S]]=min(g[refer[S]],g[refer[s]]+g[refer[S^s]]);
printf("%d\n",g[SS-1]);
return 0;
}
#include<bits/stdc++.h>
#define ll long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
#define int ll
const int MN=1e5+5;
int N,A[MN],w[MN],L[MN],R[MN],M;
int K[MN][350],Ll[350],Rr[350],bl,bel[MN];
int t[MN];
ll qz_a_1[350],qz_a_2[MN],sum_f[350];
void C(int x,int y){for(;x<=N;x+=(x&-x))t[x]+=y;}
int G(int x){int r=0;for(;x;x-=(x&-x))r+=t[x];return r;} struct edge{int to,nex;}e[MN<<1];int hr[MN],en,ind;
inline void Ins(int f,int t){e[++en]=(edge){t,hr[f]};hr[f]=en;}
inline void ins(int f,int t){Ins(f,t);Ins(t,f);}
inline void dfs(int x,int f)
{
register int i;L[x]=++ind;A[ind]=w[x];
for(i=hr[x];i;i=e[i].nex)if(e[i].to^f)dfs(e[i].to,x);
R[x]=ind;
}
signed main()
{
register int i,j,Q,opt,x,y,rt;
N=read();M=(int)((double)sqrt(N)+.5);Q=read();
for(i=1;i<=N;++i) w[i]=read();
for(i=1;i<=N;++i)
{
x=read();y=read();
if(!x) rt=y;
ins(x,y);
}
dfs(rt,0);
for(bl=0,i=1;i<=N;++i)
{
C(L[i],1),C(R[i]+1,-1);
if(i==N||i%M==0)
{
++bl;Rr[bl]=i;
for(j=1;j<=N;++j) K[j][bl]=G(j);
for(Ll[bl]=j=(bl-1)*M+1;j<=i;++j) bel[j]=bl,C(L[j],-1),C(R[j]+1,1);
}
}
for(i=1;i<=N;++i) qz_a_2[i]=qz_a_2[i-1]+A[i];
for(i=1;i<=bl;++i) qz_a_1[i]=qz_a_2[Rr[i]];
for(i=1;i<=N;++i) qz_a_2[i]-=qz_a_1[bel[i]-1];
#define cal(x) (qz_a_1[bel[x]-1]+qz_a_2[x])
for(i=1;i<=bl;++i)for(j=Ll[i];j<=Rr[i];++j)sum_f[i]+=cal(R[j])-cal(L[j]-1);
while(Q--)
{
opt=read(),x=read(),y=read();
if(opt==1)
{
x=L[x];y-=A[x];
for(i=bel[x];i<=bl;++i) qz_a_1[i]+=y;
for(i=x;i<=Rr[bel[x]];++i) qz_a_2[i]+=y;
for(i=1;i<=bl;++i) sum_f[i]+=1ll*y*K[x][i];
A[x]+=y;
}
if(opt==2)
{
ll ans=0;
if(bel[x]==bel[y]) for(i=x;i<=y;++i) ans+=cal(R[i])-cal(L[i]-1);
else
{
for(i=bel[x]+1;i<=bel[y]-1;++i) ans+=sum_f[i];
for(i=x;i<=Rr[bel[x]];++i) ans+=cal(R[i])-cal(L[i]-1);
for(i=Ll[bel[y]];i<=y;++i) ans+=cal(R[i])-cal(L[i]-1);
}
printf("%lld\n",ans);
}
}
#undef cal
return 0;
}
/*
每条边都有一个存在时间[l,r],每个询问相当于求一个时刻的答案
可以用线段树分治来维护
要支持操作是可逆的,所以采用按秩合并的dsu
2019/3/21 by pac
*/
#include<bits/stdc++.h>
#define ll long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
#define reg register
const int MN=7e4+5;
int N,M,ans[MN];
std::vector<int>id[MN];
struct edge{int u,v,nex,l,r;}e[MN<<1];int en,hr[MN];
void ins(int f,int t,int l,int r)
{
e[++en]=(edge){f,t,hr[f],l,r};hr[f]=en;
e[++en]=(edge){t,f,hr[t],l,r};hr[t]=en;
}
class LCA
{
int siz[MN],fa[MN],mx[MN],top[MN],dep[MN];
void dfs1(int x,int f)
{
dep[x]=dep[f]+1;fa[x]=f;siz[x]=1;reg int i;
for(i=hr[x];i;i=e[i].nex)if(e[i].v^f)
dfs1(e[i].v,x),siz[x]+=siz[e[i].v],siz[e[i].v]>siz[mx[x]]?mx[x]=e[i].v:0;
}
void dfs2(int x,int f,int tp)
{
top[x]=tp;if(mx[x])dfs2(mx[x],x,tp);reg int i;
for(i=hr[x];i;i=e[i].nex)if((e[i].v^f)&&(e[i].v^mx[x]))
dfs2(e[i].v,x,e[i].v);
}
public:
void init(){dfs1(1,0);dfs2(1,0,1);}
int dis(int x,int y)
{
if(!x||!y) return 0;
int r=dep[x]+dep[y];
for(;top[x]^top[y];) dep[top[x]]>dep[top[y]]?x=fa[top[x]]:y=fa[top[y]];
return r-2ll*min(dep[x],dep[y]);
}
}T;
struct Ans
{
int dl,dr,len;
Ans Max(const Ans &o,const Ans &oo){return o.len>oo.len?o:oo;}
Ans operator *(const Ans &o)
{
Ans r=Max(*this,o);
r=Max(r,(Ans){dl,o.dl,T.dis(dl,o.dl)});
r=Max(r,(Ans){dl,o.dr,T.dis(dl,o.dr)});
r=Max(r,(Ans){dr,o.dl,T.dis(dr,o.dl)});
r=Max(r,(Ans){dr,o.dr,T.dis(dr,o.dr)});
return r;
}
};
class DSU
{
Ans bl[MN],st_ori[MN];
int fa[MN],siz[MN],tp,st_l[MN],st_r[MN],ans;
int getf(int x){return x==fa[x]?x:getf(fa[x]);}
public:
void init()
{
tp=0;ans=0;reg int i;
for(i=1;i<=N;++i) fa[i]=i,siz[i]=1,bl[i]=(Ans){i,i,0};
}
void union_(int x,int y)
{
//if(getf(x)==19&&getf(y)==4) printf("%d %d\n",x,y);
x=getf(x);y=getf(y);
//printf("combine %d %d\n",x,y);
if(x==y) return;
if(siz[x]<siz[y]) std::swap(x,y);
siz[x]+=siz[y];st_l[++tp]=x;st_r[tp]=y;
fa[y]=x;st_ori[tp]=bl[x];bl[x]=bl[x]*bl[y];
ans=max(ans,bl[x].len);
//if(x==19&&bl[x].len==3) printf("find %d %d\n",y,bl[y].len);
}
void getori(int to,int p)
{
reg int l,r;
for(;tp>to;--tp)
{
l=st_l[tp],r=st_r[tp];
// printf("break %d %d\n",l,r);
siz[l]-=siz[r];fa[r]=r;
bl[l]=st_ori[tp];
}
ans=p;
}
int Tp(){return tp;}
int ANs(){return ans;}
// void print()
// {
// printf("Ans=%d\n",ans);
// for(int i=1;i<=20;++i) printf("%d: %d\n",i,bl[i].len);
// }
}dsu;
std::vector<int> T_ed[MN<<2];
void Md(int k,int l,int r,int a,int b)
{
if(l==a&&r==b){T_ed[k].push_back(en);return;}
int mid=(l+r)>>1;
if(b<=mid) Md(k<<1,l,mid,a,b);
else if(a>mid) Md(k<<1|1,mid+1,r,a,b);
else Md(k<<1,l,mid,a,mid),Md(k<<1|1,mid+1,r,mid+1,b);
}
void Solve(int x,int l,int r)
{
reg int pre=dsu.Tp(),i,res=dsu.ANs();
for(i=T_ed[x].size()-1;~i;--i){dsu.union_(e[T_ed[x][i]].u,e[T_ed[x][i]].v);}
if(l==r)
{
// if(l==15) dsu.print();
for(i=id[l].size()-1;~i;--i) ans[id[l][i]]=dsu.ANs();
}
if(l!=r)
{
reg int mid=(l+r)>>1;
Solve(x<<1,l,mid);Solve(x<<1|1,mid+1,r);
}
dsu.getori(pre,res);
}
int main()
{
// freopen("racing1.in","r",stdin);
// freopen("racing1.out","w",stdout);
N=read();M=read();
register int i,x,y,l,r;
for(i=1;i<N;++i)
{
x=read(),y=read();l=read(),r=read();
ins(x,y,l,r);Md(1,1,N,l,r);
// printf("%d %d %d %d\n",x,y,l,e[en].r);
}
for(i=1;i<=M;++i) id[read()].push_back(i);
T.init();dsu.init();Solve(1,1,N);
for(i=1;i<=M;++i) printf("%d\n",ans[i]);
}

Blog来自PaperCloud,未经允许,请勿转载,TKS!

FCS省选模拟赛 Day4的更多相关文章

  1. FCS省选模拟赛 Day1

    Description  Solution T1 shopping 目测是插板法乱搞一下 发现题解写的是容斥dp: \[ ans = \sum_i (-1)^ig[i] \] \(g[i]\)表示的有 ...

  2. FCS省选模拟赛 Day7

    Description  Solution T1 island 考虑把问题成两部分计算 纵坐标的距离和很好计算,在输入的同时一次计算了就完事 横坐标又分成两部分 分别在\(y\)轴不同侧的矩形的距离和 ...

  3. FCS省选模拟赛 Day3

    Description  Solution T1 game 咕咕咕 T2 string fail树各个节点的深度之和怎么求? 我们考虑每个前缀的深度是什么 发现这个值就相当于有多少个前缀等于它的后缀 ...

  4. FCS省选模拟赛 Day5

    传送门 Solution Code  #include<bits/stdc++.h> #define ll long long #define max(a,b) ((a)>(b)?( ...

  5. 省选模拟赛day4

    怎么说?发现自己越来越菜了 到了不写题解写不出来题目的地步了.. 这次题目我都有认真思考 尽管思考的时候状态不太好 但是 我想 再多给我时间也思考不出来什么吧 所以写一份题解. T1 n个点的有根树 ...

  6. 【洛谷比赛】[LnOI2019]长脖子鹿省选模拟赛 T1 题解

    今天是[LnOI2019]长脖子鹿省选模拟赛的时间,小编表示考的不怎么样,改了半天也只会改第一题,那也先呈上题解吧. T1:P5248 [LnOI2019SP]快速多项式变换(FPT) 一看这题就很手 ...

  7. @省选模拟赛03/16 - T3@ 超级树

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 一棵 k-超级树(k-SuperTree) 可按如下方法得到:取 ...

  8. 3.28 省选模拟赛 染色 LCT+线段树

    发现和SDOI2017树点涂色差不多 但是当时这道题模拟赛的时候不会写 赛后也没及时订正 所以这场模拟赛的这道题虽然秒想到了LCT和线段树但是最终还是只是打了暴力. 痛定思痛 还是要把这道题给补了. ...

  9. 省选模拟赛第四轮 B——O(n^4)->O(n^3)->O(n^2)

    一 稍微转化一下,就是找所有和原树差距不超过k的不同构树的个数 一个挺trick的想法是: 由于矩阵树定理的行列式的值是把邻接矩阵数值看做边权的图的所有生成树的边权乘积之和 那么如果把不存在于原树中的 ...

随机推荐

  1. 记redis一次Could not get a resource from the pool 异常的解决过程

    最近有个项目中的redis每天都会报 "Could not get a resource from the pool"的错误,而这套代码在另一地方部署又没有问题.一直找不到错误原因 ...

  2. Objective-C和 C++ 混编的要点

    Using C++ With Objective-C苹果的Objective-C编译器允许用户在同一个源文件里自由地混合使用C++和Objective-C,混编后的语言叫Objective-C++.有 ...

  3. Mongodb 学习笔记(二) :索引

    Mongodb 是基于集合建立索引 (Index),索引的作用类似于传统关系型数据库,目的是为了提高查询速度 . 如果没有建立索引, Mongodb  在读取数据时必须扫描集合中的 所有文档记录. 这 ...

  4. 【转载】 C#中List集合使用InsertRange方法在指定的位置插入另一个list集合

    在C#的List集合操作过程中,如果在集合中的某个位置插入一个新的元素对象,可以使用Insert方法进行操作.其实List集合也提供了在特定的位置插入另一个集合,然后另一个集合的数据整个写入到当前集合 ...

  5. js 的七大原则--单一原则、开闭原则、替换原则(一)

    一.前言: js 的七大设计原则: 1.单一原则 2.开闭原则 3.里氏替换原则 4.依赖倒转原则 5.接口隔离原则 6.合成复用原则 7.迪米尔法则 二.单一原则 1.定义:单一原则就是一个对象或者 ...

  6. DCL 管理用户

    DCL(Data Control Language) 使用MySQL数据库默认使用的都是 root 用户,超级管理员,拥有全部的权限. 在一个公司里面的数据库服务器上面可能同时运行这很多个项目的数据库 ...

  7. jenkins报错 Upgrading Jenkins. Failed to update the default Update Site 'default'. Plugi

    解决方案: jenkins\hudson.model.UpdateCenter.xml 文件, 将 url 中的 https://updates.jenkins.io/update-center.js ...

  8. Flask之flask-sqlalchemy

    接下来基于这个Flask项目,我们要加入Flask-SQLAlchemy让项目变得生动起来 1.加入Flask-SQLAlchemy第三方组件 from flask import Flask # 导入 ...

  9. PLC编程的基础知识的总结

    1.Programmable Logic Controller   PLC 代替计算机实现复杂的逻辑控制系统  ,可编程控制器是一种数字运算操作电子系统,转门在工业控制系统中使用而设计的,采用一种可以 ...

  10. C 语言究竟是一门怎样的语言?

    C语言是计算机及其相关专业的必修课,很多编程爱好者也是从C语言开始的编程之旅. C语言之父镇楼! 相较于GO,python等语言而言C语言真可以算是老古董了(发明于上世纪70年代),但是也正因为其历史 ...