题意:给定点数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. Oracle循环查询结果集 自定义函数

    create or replace function Fun_GetRoleIDList(d_fid char) return varchar is  rolelist varchar(2000);b ...

  2. Oracle 表空间

    表空间 编辑 本词条缺少信息栏,补充相关内容使词条更完整,还能快速升级,赶紧来编辑吧! 表空间是数据库的逻辑划分,一个表空间只能属于一个数据库.所有的数据库对象都存放在指定的表空间中.但主要存放的是表 ...

  3. PE文件头

    pe文件头查看器下载与原文地址: http://www.pc6.com/softview/SoftView_109840.html PE文件入门: PE文件总的来说是由DOS文件头.DOS加载模块.P ...

  4. DNS弹窗广告遭遇

    事情是这样的,不久前,我跟往常一样打开某新闻网页的时候,发现右下角有弹窗广告,并且在原页面任意位置点击,都会打开一个广告页面,然后原页面才能正常点击,手法太低劣了,不像是网站挂的广告,然后打开其它网页 ...

  5. Java 判断字符串第一位和最后一位,并截取

    public static void main(String[] args) { String str = "\"{\"TaxCode\":\"913 ...

  6. ExtJs 获取Dom对象

    对象指页面上的某一部分,如:Input等.我觉得在EXT JS中会有三类基本对象,htmlelement , EXT.Element和CompositeElement .分别解释一下: htmlele ...

  7. ue4 plugin的编译加载

    插件Plugin: 本来应该是指一种纯以接口与外界打交道的程序模块,在同一接口背后可以有多种实现,更换实现完全不影响客户端代码(不用重编). 但是在ue4的世界里,插件似乎不是这个意思,仅仅是一种可以 ...

  8. 【Java】:googleSearch

    google custom search是一个基于google的搜索引擎api,可以请求谷歌的搜索数据 pala pala  pala  ... 实现: 1.注册谷歌账号 2.创建google项目 1 ...

  9. Windows Desktop 调用 WinRT api

    <Reference Include="Windows"> <HintPath>..\..\..\..\..\..\Program Files (x86)\ ...

  10. python代码优化---就喜欢细节

    地址:http://www.codeproject.com/Tips/829060/Python-Code-Optimizations-Part-One 转发过来保存一下.喜欢精雕细琢,编程才有乐趣. ...