题意:给定点数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. 【译】RabbitMQ:Topics

    在前面的教程中,我们对日志系统进行了功能强化.我们使用direct类型的交换器并且为之提供了可以选择接收日志的能力,替换了只能傻乎乎的广播消息的fanout类型的交换器.尽管使用direct类型的交换 ...

  2. SAP 创建物料主数据分类视图特性

    1.CL01创建物料分类 2.去CT04中去创建特性值 创建完成之后保存, 3.创建物料的分类视图,选择相应的特性值

  3. curl模拟登录新浪微博

     这几天要做个获取新浪微博@我的信息, 又不用第三方登录,所以只能通过模拟登录来获取信息,研究的一下发现直接模拟登录微博比较困难,验证的算法比较复杂,于是绕道通过登录新浪通行证后来获取cookie 来 ...

  4. sublime插件@sublimelinter安装使用

    sublimelinter插件是一款sublime编辑器的代码校验插件,支持多种语言,对于前端来说主要包含css和js校验. 要是用这款插件 1)安装node,然后在全局安装jshint(npm in ...

  5. XE3随笔19:实例 - 借用 Google 实现全文翻译

    调用 Google 翻译的地址格式: http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=" + ...

  6. 121. Best Time to Buy and Sell Stock (一) leetcode解题笔记

    121. Best Time to Buy and Sell Stock Say you have an array for which the ith element is the price of ...

  7. Test注解的两个属性(转)

    Test注解的两个属性:expected和timeout Junit的Test注解支持两个可选的参数expected和timeout.expected声明一个测试方法必须抛出一个异常.如果不抛出异常或 ...

  8. PMI列子1

    遍历得到PMI中,是注释类型的,你可以参考一下.int num_text, thetype, thesubtype;tag_t  draft_aid_tag = NULL_TAG;UF_UI_open ...

  9. spring知识大全(4)

    5 Spring对事务的支持 一.AOP事务的含义: 事务当作一个切面,动态地织入到目标对象,形成一个代理对象. 二.Spring的事务机制 Spring支持声明式事务. Spring使用事务服务代理 ...

  10. 【java】:通用小知识

    1.将String字符串放在最前面 为了防止偶发性的NullPointerException 异常,我们通常将String放置在equals()函数的左边来实现字符串比较,如下代码: // Bad i ...