题意:给定点数n<=300000的一棵树,然后初始时每条边权值为1,接下来按照时间点先后顺序的n+m-1个操作,

操作有两种:

1.A a b 把a到b的边权改为0

2.W u 求1号点到u号点的路径权值和

思路:如果现在把题目简化为是在一条直线上的操作,每次在中间删除相邻边权值或者查询某个点到1号点的权值和

我们很容易想把询问离线,然后从1->n扫描1遍,然后用一个树状数组维护前缀和即可。。

到了本题利用dfs序显然就可以转化成线性模型,

具体的话

做到点u,

如果有一个操作1在(u, fa[u])的边,时间为t,那么在t时间点删除一个点

如果有一个操作2在u点,时间为t,那么就等价于查询1~u路径上的点数-t时间内删除的点数

回溯时把操作还原

code(stl):

 #pragma comment(linker, "/STACK:102400000,102400000")
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<string>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<stack>
#include<ctime>
#define x first
#define y second
#define M0(x) memset(x, 0, sizeof(x))
#define vii vector<int>::iterator
#define vpi vector<pair<int, int> >::iterator
#define Inf 0x7fffffff
using namespace std;
typedef pair<int, int> pii;
const int maxn = ;
vector<int> e[maxn];
vector<pii> q[maxn];
int n, m, ans[maxn<<];
int pos[maxn<<]; inline void R(int &ret){
ret = ;
bool ok = ;
for( ; ;){
int c = getchar();
if (c >= '' && c <= '') ret = (ret << ) + (ret << ) + c - '', ok = ;
else if (ok) return;
}
} void init(){
int u, v;
// for (int i = 1; i <= n; ++i) e[i].clear(), q[i].clear();
pii tmp;
for (int i = ; i < n; ++i)
R(u), R(v), e[u].push_back(v), e[v].push_back(u);
char op[];
R(m);
int nm = n + m - ;
int n1 = ;
for (int i = ; i <= nm; ++i){
scanf("%s", op);
if (op[] == 'A') ++n1;
tmp.x = i;
pos[i] = n1;
if (op[] == 'W')
R(u), tmp.y = -, q[u].push_back(tmp);
else {
R(u), R(v);
tmp.y = v, q[u].push_back(tmp);
tmp.y = u, q[v].push_back(tmp);
}
}
// cout << n1 << endl;
} int vis[maxn], s[maxn], dep[maxn];
void update(int x,const int& v){
for (; x<=n; x += x&(-x)) s[x] += v;
} int query(int x){
int res = ;
for (; x>; x -= x&(-x)) res += s[x];
return res;
} int ss;
void dfs(const int& u){
vis[u] = ;
for (vpi it = q[u].begin(); it != q[u].end(); ++it)
if (it->y != - && vis[it->y]) update(pos[it->x], );
for (vpi it = q[u].begin(); it != q[u].end(); ++it)
if (it->y == -) ans[it->x] = dep[u] - query(pos[it->x]);
for (vii it = e[u].begin(); it != e[u].end(); ++it)
if (!vis[*it]) dep[*it] = dep[u] + , dfs(*it);
for (vpi it = q[u].begin(); it != q[u].end(); ++it)
if (it->y != - && dep[it->y] < dep[u]) update(pos[it->x], -);
} void solve(){
memset(ans, -, sizeof(int) * (n+m+));
memset(vis, , sizeof(int) * (n+));
memset(s, , sizeof(int) * (n+));
dep[] = ;
dfs();
int nm = n + m;
for (int i = ; i < nm; ++i)
if (ans[i] >= ) printf("%d\n", ans[i]);
} int main(){
while (scanf("%d", &n) != EOF){
init();
solve();
}
return ;
}

code(手写链表):

 #pragma comment(linker, "/STACK:102400000,102400000")
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<string>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<stack>
#include<ctime>
#define M0(x) memset(x, 0, sizeof(x))
#define Inf 0x7fffffff
using namespace std;
const int maxn = ;
struct node{
int v, next;
} e[maxn * ];
struct qes{
int v, t, next;
} q[maxn << ];
int n, m, ans[maxn<<], last[maxn], lastq[maxn], tot, len;
int pos[maxn<<]; inline void R(int &ret){
ret = ;
bool ok = ;
for( ; ;){
int c = getchar();
if (c >= '' && c <= '') ret = (ret << ) + (ret << ) + c - '', ok = ;
else if (ok) return;
}
} inline void add(const int& u,const int& v){
e[tot] = (node){v, last[u]}, last[u] = tot++;
} inline void add_ask(const int& u,const int& v,const int& t){
q[len] = (qes){v, t, lastq[u]}, lastq[u] = len++;
} void init(){
int u, v;
memset(last, -, sizeof(last));
memset(lastq, -, sizeof(lastq));
len = tot = ;
for (int i = ; i < n; ++i)
R(u), R(v), add(u, v), add(v, u);
char op[];
R(m);
int nm = n + m - ;
int n1 = ;
for (int i = ; i <= nm; ++i){
scanf("%s", op);
if (op[] == 'A') ++n1;
pos[i] = n1;
if (op[] == 'W')
R(u), add_ask(u, -, i);
else {
R(u), R(v);
add_ask(u, v, i), add_ask(v, u, i);
}
}
// cout << n1 << endl;
} int vis[maxn], s[maxn], dep[maxn];
void update(int x,const int& v){
for (; x<=n; x += x&(-x)) s[x] += v;
} int query(int x){
int res = ;
for (; x>; x -= x&(-x)) res += s[x];
return res;
} void dfs(const int& u){
vis[u] = ;
for (int p = lastq[u]; ~p; p = q[p].next)
if (q[p].v != - && vis[q[p].v]) update(pos[q[p].t], );
for (int p = lastq[u]; ~p; p = q[p].next)
if (q[p].v == -) ans[q[p].t] = dep[u] - query(pos[q[p].t]);
for (int p = last[u]; ~p; p = e[p].next)
if (!vis[e[p].v]) dep[e[p].v] = dep[u] + , dfs(e[p].v);
for (int p = lastq[u]; ~p; p = q[p].next)
if (q[p].v != - && dep[q[p].v] < dep[u]) update(pos[q[p].t], -);
} void solve(){
memset(ans, -, sizeof(int) * (n+m+));
memset(vis, , sizeof(int) * (n+));
memset(s, , sizeof(int) * (n+));
dep[] = ;
dfs();
int nm = n + m;
for (int i = ; i < nm; ++i)
if (ans[i] >= ) printf("%d\n", ans[i]);
} int main(){
// freopen("a.in", "r", stdin);
// freopen("a.out", "w", stdout);
while (scanf("%d", &n) != EOF){
init();
solve();
}
return ;
}

[poi2007]mem的更多相关文章

  1. Linux命令自己总结

    对于每一个Linux学习者来说,了解Linux文件系统的目录结构,是学好Linux的至关重要的一步.,深入了解linux文件目录结构的标准和每个目录的详细功能,对于我们用好linux系统只管重要,下面 ...

  2. BZOJ 1103: [POI2007]大都市meg [DFS序 树状数组]

    1103: [POI2007]大都市meg Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2221  Solved: 1179[Submit][Sta ...

  3. 实时事件统计项目:优化flume:用file channel代替mem channel

    背景:利用kafka+flume+morphline+solr做实时统计. solr从12月23号开始一直没有数据.查看日志发现,因为有一个同事加了一条格式错误的埋点数据,导致大量error. 据推断 ...

  4. BZOJ1098: [POI2007]办公楼biu

    从问题可以看出是求补图的连通块及点数 但补图太大.所以考虑缩小规模. 当一个点归属于一个连通块后,它以后就不需要了.所以可以用链表,删去这个点,也就减小了规模. 一个点开始bfs,每个点只会进队一次, ...

  5. BZOJ1097: [POI2007]旅游景点atr

    ..k次最短路后,考虑如何满足先走一些点 用状压dp,每一个点考虑它所需要经过的点a[i],当当前走过的点包含a[i]时,i 这个点才可以到达. 写的时候用记忆化搜索. #include<bit ...

  6. BWA MEM算法

    现在BWA大家基本上只用其mem算法了,无论是二代还是三代比对到参考基因组上,BWA应用得最多的就是在重测序方面. Aligning sequence reads, clone sequences a ...

  7. BZOJ 1101: [POI2007]Zap

    1101: [POI2007]Zap Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2262  Solved: 895[Submit][Status] ...

  8. BZOJ 1100: [POI2007]对称轴osi

    1100: [POI2007]对称轴osi Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 630  Solved: 243[Submit][Statu ...

  9. BZOJ 1111: [POI2007]四进制的天平Wag

    1111: [POI2007]四进制的天平Wag Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 223  Solved: 151[Submit][St ...

随机推荐

  1. scp详解

    scp 命令 ================== scp 可以在 2个 linux 主机间复制文件: 命令基本格式:        scp [可选参数] file_source file_targe ...

  2. final评论II

    1.  Nice  项目:约跑软件       在此次六个发布作品中,此作品是唯一基于Androrid开发app.并且此作品创意和实用性很高的,跑步是人们日渐热爱的一个活动,用户广泛,并且在网上沟通交 ...

  3. Java(异常处理)动手动脑

    1>请阅读并运行AboutException.java示例,然后通过后面的几页PPT了解Java中实现异常处理的基础知识. import javax.swing.*; class AboutEx ...

  4. keepalived+mysql实现双主高可用

    环境: DB1:centos6.8.mysql5.5.192.168.2.204  hostname:bogon DB2:centos6.8.mysql5.5.192.168.2.205  hostn ...

  5. eclipse无法创建Server

    报错:Cannot create a server using the selected type1.退出eclipse 2.到[工程目录下]/.metadata/.plugins/org.eclip ...

  6. MVc Forms Membership rolemanage 角色权限验证管理

    Forms  登录验证Membership 权限验证rolemanage 角色管理 以往的项目中只有单纯的Forms 验证今天想把这三个结合到mvc 中发现要导入aspnet_ 相关表,但是有个问题验 ...

  7. adv联系题

    http://www.cnblogs.com/kuangbin/archive/2011/07/29/2120667.html(新)

  8. redis五种数据类型的使用(zz)

    redis五种数据类型的使用 redis五种数据类型的使用 (摘自:http://tech.it168.com/a2011/0818/1234/000001234478_all.shtml ) 1.S ...

  9. Twitter Bootstrap

    Twitter Bootstrap是一个HTML/CSS/JS框架,适用于移动设备优先的响应式网页开发.主要涉及: HTML:为已有的H5标签扩展了自定义属性 data-* CSS : Reset + ...

  10. shell学习--grep2

    grep相关的练习,解释下面grep表达式的含义: grep '\<Tom\>' file 打印file中包含单词 Tom的行 grep 'Tome Savage' file 打印file ...