题意:给定点数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. .net妹纸转Java---java环境的搭建,myeclipse10.0 的安装环境变量配置和破解

    啦啦啦 ,因为公司项目需要,从我大火炉--大武汉被拖到了更大的火炉--大广西  其实一开始 我的内心是拒绝的. 但是我在大武汉呆了近2年木有出过远门,对, 生活除了眼前的苟且,还有远方的苟且.怀揣这样 ...

  2. mvc 4 ActionFilterAttribute 特性,进行权限验证

    权限验证: /// <summary> /// 管理员身份验证 /// </summary> public class BasicAuthenticationAttribute ...

  3. 我眼中的项目leader

    个人觉得项目leader应该具备一下基础: 1.技术能力 2.领导能力 3.过滤产品不合理需求能力 4.项目周期把控能力

  4. ff

    public class MyListenerProcessor implements BeanPostProcessor { @Override public Object postProcessB ...

  5. winform 异步读取数据 小实例

    这几天对突然对委托事件,异步编程产生了兴趣,大量阅读前辈们的代码后自己总结了一下. 主要是实现 DataTable的导入导出,当然可以模拟从数据库读取大量数据,这可能需要一定的时间,然后 再把数据导入 ...

  6. Knockout.Js官网学习(value绑定)

    前言 value绑定是关联DOM元素的值到view model的属性上.主要是用在表单控件<input>,<select>和<textarea>上. 当用户编辑表单 ...

  7. 移动开发tip

    input点击出现背景色和边框,加入样式 -webkit-tap-highlight-color: rgba(255,255,255,0); ios下按钮糊掉,样式表不怎么起作用,使用-webkit- ...

  8. Android之GridView

    <GridView android:id="@+id/gridView" android:layout_width="match_parent" andr ...

  9. error C2065: “CDatabase”: 未声明的标识符

    使用vc++与access的接口时出现错误“error C2065: “CDatabase”: 未声明的标识符” 解决方法: 添加 #include "afxdb.h"

  10. MySQL数据库sql语句的一些简单优化

    1.查询条件的先后顺序 有多个查询条件时,要把效率高能更精确筛选记录的条件放在后边.因为MySQL解析sql语句是从后往前的(不知是否准确). 例: select a.*,b.* from UsrIn ...