zoj 树状数组经典 ( 未解)
来源:互联网 发布:黑暗启示录2bt版java 编辑:程序博客网 时间:2024/06/13 09:57
问题:n个点,对于每个点i,都有一条连向i+1的有向边,另外有m条其他的有向边,有q个询问(u,v)求u到v的最短路
将m条有向边和q个询问对所表示的点对一起排序,(u,v)u大的排前,u一样的v小的排前,u和v一样大的先处理插入的再处理询问的;
边插入边询问;
树状数组里存的是右端点在v之后的询问的结果的差值
(1)对于(u,v)u<v的这种边,保证在查询到(u,v)之前,所有的(u2,v2)u<u2<v2<v都已经插入好,同时,(u2,v2) u2<u或者(u2=u && v2>v) 的那些还没插入,树状数组存mat[u1][v1]-(d[v1]-d[u1])的最小值,查询时在加上(d[v]-d[u])
(2)对于(u,v)u>v的这种边,保证在查询到(u,v)之前,所有(u2,v2) v2<v<u<u2的都已经插入好,同时,(u2,v2) v<v2<u2<u那些不能插入。树状数组里存的是mat[u2][v2]+(d[u2]-d[v2]),查询再减去(d[u]-d[v])
所以要通过排序来操作
- #include<iostream>
- #include<cstring>
- #include <cstdio>
- #include <algorithm>
- using namespace std;
- #define ll long long
- ll b[105000];
- int N;
- int lowbit(int x)
- {
- return x&(-x);
- }
- void upd(int x,ll val)
- {
- while(x<=N)
- {
- b[x]=min(b[x],val);
- x+=lowbit(x);
- }
- }
- ll query(int x)
- {
- ll res=(1LL<<60);
- while(x)
- {
- res=min(res,b[x]);
- x-=lowbit(x);
- }
- return res;
- }
- struct Point
- {
- int u,v,kind;
- ll ind;
- }p[400500];
- bool cmp(Point left,Point right)
- {
- if(left.u==right.u && left.v==right.v)
- return left.kind<right.kind; // insert before query
- if(left.u==right.u)
- return left.v<right.v;
- return left.u>right.u;
- }
- ll s[100500];
- int ans[200500];
- int main ()
- {
- int n,m,q,u,v,ind;
- while(scanf("%d%d",&n,&m)!=EOF)
- {
- for(int i=1;i<n;++i)
- scanf("%d",&ind),s[i+1]=ind+s[i];
- for(int i=1;i<=m;++i)
- {
- scanf("%d%d%lld",&p[i].u,&p[i].v,&p[i].ind);
- p[i].kind=0;
- }
- scanf("%d",&q);
- for(int i=1;i<=q;++i)
- {
- scanf("%d%d",&p[m+i].u,&p[m+i].v);
- p[m+i].kind=1;
- p[m+i].ind=i;
- }
- sort(p+1,p+1+m+q,cmp);
- N=n;
- memset(ans,0,sizeof(ans)); // 一些询问u=v,不初始化都为0,会错
- memset(b,0,sizeof(b));
- for(int i=1;i<=m+q;++i)
- {
- if(p[i].kind==0 && p[i].u<p[i].v)
- upd(p[i].v,p[i].ind-(s[p[i].v]-s[p[i].u]));
- if(p[i].kind==1 && p[i].u<p[i].v)
- ans[p[i].ind]=s[p[i].v]-s[p[i].u]+query(p[i].v);
- }
- for(int i=1;i<=n;++i)
- b[i]=(1LL<<60);
- for(int i=1;i<=m+q;++i)
- {
- if(p[i].kind==0 && p[i].u>p[i].v)
- upd(p[i].v,p[i].ind+(s[p[i].u]-s[p[i].v]));
- if(p[i].kind==1 && p[i].u>p[i].v)
- ans[p[i].ind]=query(p[i].v)-(s[p[i].u]-s[p[i].v]);
- }
- for(int i=1;i<=q;++i)
- printf("%d\n",ans[i]);
- }
- return 0;
- }
- zoj 树状数组经典 ( 未解)
- zoj 3724 树状数组经典
- zoj 3724 树状数组
- 树状数组经典
- 树状数组经典讲解
- zoj 3279【树状数组+二分】
- ZOJ 3635 树状数组+二分
- ZOJ 3635 树状数组+二分
- hdu4358 树状数组-非常经典
- HDU 4267 经典树状数组
- ZOJ 3612 树状数组 第K大数
- zoj 3635 树状数组加二分
- ZOJ 3279 Ants 二分树状数组
- ZOJ 3279 树状数组 题库221页
- ZOJ 2112 [树状数组套主席树]
- ZOJ 3813 Alternating Sum 树状数组
- ZOJ 3157 Weapon --计算几何+树状数组
- ZOJ:3634Bounty hunter(二分+树状数组)
- 4.5Fasade 外观模式
- 超时时间已到。超时时间已到,但是尚未从池中获取连接
- svn权限管理
- Java编程中“为了性能”要做的几点
- SpringMVC3+Hibernate+MySQL CRUD 小案例(翻译)
- zoj 树状数组经典 ( 未解)
- Java从网络读取图片并保存至本地 .
- cookie ,session,servletContext的区分
- __asm__ __volatile__("": : :"memory")
- OnInitialUpdate函数 UpdateAllViews函数 说明
- 界面闪烁以及图形重绘不彻底的另类原因
- STL vector 容器介绍
- JBoss配置二
- ubuntu下安装openMPI