HDU 3966 Aragorn's Story 动态树 树链剖分
Aragorn's Story
Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
For each case, The first line contains three integers N, M, P which means there will be N(1 ≤ N ≤ 50000) camps, M(M = N-1) edges and P(1 ≤ P ≤ 100000) operations. The number of camps starts from 1.
The next line contains N integers A1, A2, ...AN(0 ≤ Ai ≤ 1000), means at first in camp-i has Ai enemies.
The next M lines contains two integers u and v for each, denotes that there is an edge connects camp-u and camp-v.
The next P lines will start with a capital letter 'I', 'D' or 'Q' for each line.
'I', followed by three integers C1, C2 and K( 0≤K≤1000), which means for camp C1, C2 and all camps on the path from C1 to C2, increase K soldiers to these camps.
'D', followed by three integers C1, C2 and K( 0≤K≤1000), which means for camp C1, C2 and all camps on the path from C1 to C2, decrease K soldiers to these camps.
'Q', followed by one integer C, which is a query and means Aragorn wants to know the number of enemies in camp C at that time.
I
Q
D
Q
Q
【Hint】
2.Huge input, be careful.
/* ***********************************************
MYID : Chen Fan
LANG : G++
PROG : HDU 3966
************************************************ */ #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue> using namespace std; #define MAXN (int)5E4+10
#define MAXM (int)1E5+10 typedef struct nod
{
int a,b;
} node;
node edge[MAXM]; bool op(node a,node b)
{
if (a.a==b.a) return a.b<b.b;
else return a.a<b.a;
} int sons[MAXN][];
int father[MAXN],size[MAXN],data[MAXN],change[MAXN];
int start[MAXN],num[MAXN];
bool root[MAXN]; void bfs(int s)
{
queue<int>q;
q.push(s);
root[s]=true;
change[s]=;
while(!q.empty())
{
int now=q.front();
for (int i=;i<num[now];i++)
if (!root[edge[start[now]+i].b])
{
father[edge[start[now]+i].b]=now;
root[edge[start[now]+i].b]=true;
change[edge[start[now]+i].b]=;
q.push(edge[start[now]+i].b);
}
q.pop();
}
} void down(int x)
{
if (change[x])
{
data[x]+=change[x];
change[sons[x][]]+=change[x];
change[sons[x][]]+=change[x];
change[x]=;
}
} void rotate(int x,int w) //rotate(node,0/1)
{
int y=father[x]; down(y);
down(x); sons[y][!w]=sons[x][w];
if (sons[x][w]) father[sons[x][w]]=y;
father[x]=father[y];
if (father[y]&&(!root[y])) sons[father[y]][y==sons[father[y]][]]=x;
sons[x][w]=y;
father[y]=x; if (root[y])
{
root[x]=true;
root[y]=false;
}
} void splay__(int x) //splay(node)
{
down(x);
while(!root[x])
{
if (root[father[x]]) rotate(x,x==sons[father[x]][]);
else
{
int t=father[x];
int w=(sons[father[t]][]==t);
if (sons[t][w]==x)
{
rotate(x,!w);
rotate(x,w);
} else
{
rotate(t,w);
rotate(x,w);
}
}
}
} void splay(int x) //splay(node)
{
down(x);
while(!root[x])
{
if (sons[father[x]][]==x) rotate(x,);
else rotate(x,);
}
} void access(int v)
{
int u=v;
v=;
while(u)
{
splay(u);
down(u);
root[sons[u][]]=true;
sons[u][]=v;
root[v]=false;
v=u;
u=father[u];
}
} void update(int v,int u,int k)
{
access(v);
v=;
while(u)
{
splay(u);
if (!father[u])
{
data[u]+=k;
change[v]+=k;
change[sons[u][]]+=k;
return;
}
down(u);
root[sons[u][]]=true;
sons[u][]=v;
root[v]=false;
v=u;
u=father[u];
}
} int INT() {
char ch;
int res;
bool neg;
while (ch = getchar(), !isdigit(ch) && ch != '-')
;
if (ch == '-') {
neg = true;
res = ;
} else {
neg = false;
res = ch - '';
}
while (ch = getchar(), isdigit(ch))
res = res * + ch - '';
return neg ? -res : res;
} char CHAR() {
char res;
while (res = getchar(), !isalpha(res))
;
return res;
} int main()
{
freopen("3966.txt","r",stdin); int n,m,p;
while(scanf("%d%d%d",&n,&m,&p)!=EOF)
{
memset(father,,sizeof(father));
memset(sons,,sizeof(sons)); for (int i=;i<=n;i++) data[i]=INT(); for (int i=;i<=m;i++)
{
int a,b;
a=INT();
b=INT();
edge[i*].a=a;
edge[i*].b=b;
edge[i*-].a=b;
edge[i*-].b=a;
}
m*=;
sort(&edge[],&edge[m+],op);
memset(num,,sizeof(num));
int o=-;
for (int i=;i<=m;i++)
{
if (o!=edge[i].a)
{
o=edge[i].a;
start[o]=i;
}
num[o]++;
}
memset(root,,sizeof(root));
bfs(); for (int i=;i<=p;i++)
{
char s;
s=CHAR();
switch(s)
{
case 'I':
int c1,c2,k;
c1=INT();c2=INT();k=INT();
update(c1,c2,k);
break;
case 'D':
c1=INT();c2=INT();k=INT();
update(c1,c2,-k);
break;
case 'Q':
int c;
c=INT();
splay(c);
printf("%d\n",data[c]);
}
}
} return ;
}
/* ***********************************************
MYID : Chen Fan
LANG : G++
PROG : HDU 3966_TreeCut
************************************************ */ #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm> using namespace std; #define MAXN (int)5E4+10
#define MAXM (int)1E5+10 int n; int son[MAXN];
int father[MAXN],size[MAXN],level[MAXN],data[MAXN],top[MAXN];
int start[MAXN],num[MAXN]; typedef struct nod
{
int a,b;
} node;
node edge[MAXM]; bool op(node a,node b)
{
if (a.a==b.a) return a.b<b.b;
else return a.a<b.a;
} int lowbit(int s)
{
return s&(-s);
}
int c[MAXN],pos[MAXN];
int tot; void update(int x,int s)
{
while (x<=n)
{
c[x]+=s;
x+=lowbit(x);
}
} int sum(int x)
{
int t=;
while (x>)
{
t+=c[x];
x-=lowbit(x);
}
return t;
} void dfs(int now,int front,int d)
{
level[now]=d;
father[now]=front;
size[now]=;
for (int i=;i<num[now];i++)
{
int temp=edge[start[now]+i].b;
if (temp!=front)
{
dfs(temp,now,d+);
size[now]+=size[temp];
if (son[now]==||size[temp]>size[son[now]]) son[now]=temp;
}
}
} int q[MAXN];
void bfs()
{
int head=,tail=;
q[]=;
level[]=;
father[]=;
while(head<=tail)
{
int now=q[head];
size[now]=;
for (int i=;i<num[now];i++)
{
int temp=edge[start[now]+i].b;
if (temp!=father[now])
{
father[temp]=now;
level[temp]=level[now]+;
tail++;
q[tail]=temp;
}
}
head++;
}
for (int i=n;i>=;i--)
{
int now=q[i];
if (father[now])
{
size[father[now]]+=size[now];
if (son[father[now]]==||size[now]>size[son[father[now]]])
son[father[now]]=now;
}
} for (int i=;i<=n;i++)
{
int now=q[i];
if (son[father[now]]==now) top[now]=top[father[now]];
else
{
top[now]=now;
while(now)
{
tot++;
pos[now]=tot;
now=son[now];
}
}
}
} void treecut(int now,int root)
{
top[now]=root;
tot++;
pos[now]=tot; if (!son[now]) return ;
treecut(son[now],root); for (int i=;i<num[now];i++)
{
int temp=edge[start[now]+i].b;
if (temp!=father[now]&&temp!=son[now]) treecut(temp,temp);
}
} void change(int x,int y,int value)
{
while(top[x]!=top[y])
{
if (level[top[x]]<level[top[y]]) swap(x,y);
update(pos[top[x]],value);
update(pos[x]+,-value);
x=father[top[x]];
}
if (level[x]>level[y]) swap(x,y); update(pos[x],value);
update(pos[y]+,-value);
} int main()
{
freopen("3966.txt","r",stdin); int m,p;
while(scanf("%d%d%d",&n,&m,&p)!=EOF)
{
for (int i=;i<=n;i++) scanf("%d",&data[i]); for (int i=;i<=m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
edge[i*].a=a;
edge[i*].b=b;
edge[i*-].a=b;
edge[i*-].b=a;
}
m*=;
sort(&edge[],&edge[m+],op);
memset(num,,sizeof(num));
int o=-;
for (int i=;i<=m;i++)
{
if (o!=edge[i].a)
{
o=edge[i].a;
start[o]=i;
}
num[o]++;
} memset(son,,sizeof(son));
tot=;
//dfs(1,0,0);
//treecut(1,1);
bfs(); memset(c,,sizeof(c));
for (int i=;i<=n;i++)
{
update(pos[i],data[i]);
update(pos[i]+,-data[i]);
} for (int i=;i<=p;i++)
{
char s;
s=getchar();
while (s!='Q'&&s!='I'&&s!='D') s=getchar();
if (s=='Q')
{
int cc;
scanf("%d",&cc);
printf("%d\n",sum(pos[cc]));
} else
{
int c1,c2,k;
scanf("%d%d%d",&c1,&c2,&k);
if (s=='D') k=-k;
change(c1,c2,k);
}
}
} return ;
}
HDU 3966 Aragorn's Story 动态树 树链剖分的更多相关文章
- HDU 3966 Aragorn's Story(树链剖分)
HDU Aragorn's Story 题目链接 树抛入门裸题,这题是区间改动单点查询,于是套树状数组就OK了 代码: #include <cstdio> #include <cst ...
- HDU 3966 Aragorn's Story 树链剖分+树状数组 或 树链剖分+线段树
HDU 3966 Aragorn's Story 先把树剖成链,然后用树状数组维护: 讲真,研究了好久,还是没明白 树状数组这样实现"区间更新+单点查询"的原理... 神奇... ...
- hdu 3966 Aragorn's Story(树链剖分+树状数组)
pid=3966" target="_blank" style="">题目链接:hdu 3966 Aragorn's Story 题目大意:给定 ...
- HDU - 3966 Aragorn's Story(树链剖分入门+线段树)
HDU - 3966 Aragorn's Story Time Limit: 3000MS Memory Limit: 32768KB 64bit IO Format: %I64d & ...
- Hdu 3966 Aragorn's Story (树链剖分 + 线段树区间更新)
题目链接: Hdu 3966 Aragorn's Story 题目描述: 给出一个树,每个节点都有一个权值,有三种操作: 1:( I, i, j, x ) 从i到j的路径上经过的节点全部都加上x: 2 ...
- HDU 3966 Aragorn's Story (树链点权剖分,成段修改单点查询)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3966 树链剖分的模版,成段更新单点查询.熟悉线段树的成段更新的话就小case啦. //树链剖分 边权修 ...
- hdu 3966 Aragorn's Story(树链剖分+树状数组/线段树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3966 题意: 给出一棵树,并给定各个点权的值,然后有3种操作: I C1 C2 K: 把C1与C2的路 ...
- hdu 3966 Aragorn's Story(树链剖分+区间修改+单点查询)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3966 题意:给一棵树,并给定各个点权的值,然后有3种操作: I C1 C2 K: 把C1与C2的路径上 ...
- HDU 3966 Aragorn's Story (树链剖分+树状数组)
Aragorn's Story Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
随机推荐
- 7.编写Java应用程序。首先,定义一个Print类,它有一个方法void output(int x),如果x的值是1,在控制台打印出大写的英文字母表;如果x的值是2,在 控制台打印出小写的英文字母表。其次,再定义一个主类——TestClass,在主类 的main方法中创建Print类的对象,使用这个对象调用方法output ()来打印出大 小写英文字母表。
package com.bao; public class Print1 { int x; void output() { if(x==1) { System.out.println("AB ...
- iOS 视图控制器生命周期
1.init: 2.viewDidLoad: 3.viewWillAppear: 4.viewDidAppear: 5.viewWillDisappear; 6.viewDidDisappear
- winsock编程WSAEventSelect模型
winsock编程WSAEventSelect模型 WSAEventSelect模型和WSAAsyncSelec模型类似,都是用调用WSAXXXXXSelec函数将socket和事件关联并注册到系统, ...
- MySQL python组件安装
可使用pip进行安装 pip install MySQL-python 如出现以下错误 _mysql.c::: 错误:my_config.h:没有那个文件或目录 _mysql.c::: 错误:mysq ...
- Internet History, Technology and Security (Get Started)
Abstract 课程名称:互联网的历史.技术和安全 coursera地址 制作方:密歇根大学(University of Michigan) 教师:Charles Severance, Associ ...
- Chapter 2 Open Book——8
But as far as I could tell, life worked that way most of the time. 但是即使我这么说,生活大多数时间还是这样的. 但就我所能告诉你的, ...
- 初识mongo
进入mongo /usr/local/mongodb/bin/mongo --host 查看所有db show dbs 查看当前进入的db db 查看当前db的所有collection show co ...
- postgres-xl 集体搭建
pgxl 集群搭建 一 预备 1 下载安装解压源码 /opt/ curl -O http://files.postgres-xl.org/postgres-xl95r1beta1.tar.gz tar ...
- connectVisualVMtoTomcat
connectVisualVMtoTomcat 抱ラ花瘠 荬捻怵 鞅讣囚 骝珈 名诡氩 祉逦戳阜 骚须ⅳ 破竹的从骑士的肩甲出切了下去嚓 闼原 奇荛糠 社獭池 杨叔你养的这些望月螓 ...
- 使用Chrome DevTools的Timeline和Profiles提高Web应用程序的性能
来源: http://www.oschina.net/translate/performance-optimisation-with-timeline-profiles 我们都希望创建高性能的Web应 ...