[三进制倍增 || 可并堆] BZOJ 4003 [JLOI2015]城池攻占
2016-04-30 14:02
519 查看
蒟蒻想起来自己还不会可并堆诶
出题人卡倍增,那么淡定的写了个三进制倍增
UPD:random heap 很兹瓷哇
出题人卡倍增,那么淡定的写了个三进制倍增
#include<cstdio> #include<cstdlib> #include<algorithm> #include<iostream> #include<cmath> #include<limits> #include<cstring> #define V G[p].v using namespace std; inline char nc() { static char buf[100000],*p1=buf,*p2=buf; if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; } return *p1++; } inline void read(int &x) { char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b; } inline void read(long long &x) { char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b; } inline int dcmp(long double a,long double b){ if (fabs(a-b)<1e-6) return 0; if (a<b) return -1; return 1; } const int N=300005; struct edge{ int u,v; int f,a; int next; }; edge G[N*2]; int head ,inum; inline void add(int u,int v,int f,int a,int p) { G[p].u=u; G[p].v=v; G[p].f=f; G[p].a=a; G[p].next=head[u]; head[u]=p; } int n,m; int depth ; long long h ; long double val ,K ,B ; long double maximum=-1e100; void dfs(int u,long double k,long double b) { val[u]=k*h[u]+b; K[u]=k; B[u]=b; maximum=max(maximum,val[u]); for (int p=head[u];p;p=G[p].next) { depth[V]=depth[u]+1; if (G[p].f==1) dfs(V,k*G[p].a,b); else dfs(V,k,k*G[p].a+b); } } int fat [13]; long double maxv [13]; inline void Pre() { for (int k=1;k<13;k++) for (int i=1;i<=n;i++) fat[i][k]=fat[fat[fat[i][k-1]][k-1]][k-1]; for (int k=1;k<13;k++) maxv[0][k]=(numeric_limits<long double>::max)(); for (int i=1;i<=n;i++) maxv[i][0]=val[i]; for (int k=1;k<13;k++) for (int i=1;i<=n;i++) maxv[i][k]=max(max(maxv[i][k-1],maxv[fat[i][k-1]][k-1]),maxv[fat[fat[i][k-1]][k-1]][k-1]); } int ans1 ,ans2 ; int main() { int iv,f,a; freopen("t.in","r",stdin); freopen("t.out","w",stdout); read(n); read(m); for (int i=1;i<=n;i++) read(h[i]); for (int i=2;i<=n;i++) read(iv),read(f),read(a),add(iv,i,f,a,++inum),fat[i][0]=iv; depth[1]=1; dfs(1,1,0); Pre(); for (int i=1;i<=m;i++) { int S,iC,T; long double C; read(iC); read(S); T=S; C=iC; C=K[S]*C+B[S]; for (int k=12;k>=0;k--) { if (dcmp(max(maxv[T][k],maxv[fat[T][k]][k]),C)<=0) T=fat[fat[T][k]][k]; if (dcmp(maxv[T][k],C)<=0) T=fat[T][k]; } ans1[i]=depth[S]-depth[T]; ans2[T]++; } for (int i=1;i<=n;i++) printf("%d\n",ans2[i]); for (int i=1;i<=m;i++) printf("%d\n",ans1[i]); return 0; }
UPD:random heap 很兹瓷哇
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> using namespace std; typedef long long ll; inline char nc() { static char buf[100000],*p1=buf,*p2=buf; if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; } return *p1++; } inline void read(int &x) { char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b; } inline void read(ll &x) { char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b; } const int N=300005; int ran(){static int x=31253125;x+=(x<<4)+1;return x&65536;} struct node{ node *l,*r; ll key; int idx; ll k,b; void modify(ll _k,ll _b){ key=key*_k+_b; k=k*_k; b=_k*b+_b; } void pushdown(){ if (!(k==1 && b==0)) { if (l) l->modify(k,b); if (r) r->modify(k,b); k=1; b=0; } } }nodes ; node *M(node *p,node *q){ if (!p||!q) return (p?p:q); if (p->key>q->key) return M(q,p); p->pushdown(); ran()?p->r=M(p->r,q):p->l=M(p->l,q); return p; } node *root ; int n,m; int fa ,deg ,depth ; ll h ,f ,a ; int ans1 ,ans2 ; int S ; int Stack ,pnt; int main() { ll c; int s; freopen("t.in","r",stdin); freopen("t.out","w",stdout); read(n); read(m); memset(ans2,-1,sizeof(ans2)); for (int i=1;i<=n;i++) read(h[i]); for (int i=2;i<=n;i++) read(fa[i]),read(f[i]),read(a[i]),deg[fa[i]]++,depth[i]=depth[fa[i]]+1; for (int i=1;i<=n;i++) root[i]=NULL; for (int i=1;i<=m;i++) { read(c); read(s); S[i]=s; nodes[i].key=c; nodes[i].l=nodes[i].r=NULL; nodes[i].idx=i; nodes[i].k=1; nodes[i].b=0; root[s]=M(root[s],nodes+i); } for (int i=1;i<=n;i++) if (!deg[i]) Stack[++pnt]=i; while (pnt){ s=Stack[pnt--]; while (root[s] && root[s]->key<h[s]) { ans1[s]++; ans2[root[s]->idx]=depth[S[root[s]->idx]]-depth[s]; root[s]->pushdown(); root[s]=M(root[s]->l,root[s]->r); } if (root[s]) { if (f[s]==0) root[s]->modify(1,a[s]); if (f[s]==1) root[s]->modify(a[s],0); } if (fa[s]) { root[fa[s]]=M(root[fa[s]],root[s]); if (!(--deg[fa[s]])) Stack[++pnt]=fa[s]; } } for (int i=1;i<=m;i++) if (ans2[i]==-1) ans2[i]=depth[S[i]]+1; for (int i=1;i<=n;i++) printf("%d\n",ans1[i]); for (int i=1;i<=m;i++) printf("%d\n",ans2[i]); return 0; }
相关文章推荐
- Linux内核学习总结
- POJ3422 Kaka's Matrix Travels
- golang协程资源占有率
- HDOJ(HDU) 2091 空心三角形
- HDOJ(HDU) 2091 空心三角形
- Java重载(OverLoad)的理解
- php file_put_contents() 读取数据不换行问题
- Java的对象是采用值传递还是引用传递?
- 发表在IBM Developworks上的文章,Spark Streaming 图片处理案例介绍
- 面试中的排序算法总结
- 排序问题-快速排序
- [乱搞 暴力 并查集] BZOJ 3563 DZY Loves Chinese
- poj 2777 Count Color(线段树区间更新+位运算)
- Codeforces Round #349 (Div. 2) - C
- Shell编程入门总结(三)
- wampserver使用过程中遇到的问题及相关配置
- HDU 1036 - Average is not Fast Enough!
- Google推荐的图片加载库Glide介绍
- mesos上运行docker registry
- Boost Test学习总结(C++)