BZOJ4150 AMPPZ2014 The Staging


Description

在舞台上有n个枪手,第i个枪手瞄准了第p[i]个枪手,将于第u[i]秒开枪。一个枪手如果成功开枪,

那么被瞄准的枪手会立刻死亡。

现在给出q次修改操作,请在一开始和每次修改操作后统计出最后存活的枪手个数。

Input

第一行包含一个正整数n(1<=n<=200000),表示枪手的个数。

第二行包含n个互不相同的正整数p[1],p[2],...,p[n](1&lt;=p[i]&lt;=n,p[i]!=i)" role="presentation" style="position: relative;">p[1],p[2],...,p[n](1<=p[i]<=n,p[i]!=i)p[1],p[2],...,p[n](1<=p[i]<=n,p[i]!=i),依次表示每个枪手的目标。

第三行包含n个正整数u[1],u[2],...,u[n](1&lt;=u[i]&lt;=109)" role="presentation" style="position: relative;">u[1],u[2],...,u[n](1<=u[i]<=109)u[1],u[2],...,u[n](1<=u[i]<=109),依次表示每个枪手的开枪时间。

接下来一行包含一个正整数q,表示修改操作的个数。

接下来q行,每行包含两个正整数k,v(1&lt;=k&lt;=n,1&lt;=v&lt;=109)" role="presentation" style="position: relative;">(1<=k<=n,1<=v<=109)(1<=k<=n,1<=v<=109),表示把u[k]修改为v。

数据保证任何时刻任意两个枪手的开枪时间都不同。

Output

第一行包含一个正整数,即在进行修改之前最后存活的枪手个数。

接下来q行,每行包含一个正整数,第i行输出在第i次修改之后最后存活的枪手个数。

Sample Input

4

2 3 4 1

1 2 3 4

3

1 8

2 7

3 6

Sample Output

2

2

1

1


线段树好题

真的好

上次好像是dcy还是谁的给我们考过一次

然后无奈暴力50分

考完听完评奖望之生畏也就没改留坑了

结果这次cdsf又给我们考,因为不想接受暴零的未来

所以拼命想,然后把它做出来了

结果是好的


接下来讲正事

首先我们有很多的环

然后我们考虑从中间的某一个点把这个环剖开

然后变成一条链

然后我们有许许多多的单点修改,全局查询。。。想到了啥

线段树啊

然后发现一个人是否存活之和它之前的人有没有机会发出炮弹有关

所以对于一个区间,我们考虑维护左端点的人可以存活的时候,右端点的人是否存活,在这个时候区间中可以留下的人一共有多少,左端点的人不能存活同理,顺便维护一下一个区间的左右端点的u

然后我们考虑怎么合并两个区间

首先,对于左端点可以存活的时候,来看看左区间的右端点的人活不活的了,如果活的了就判断一下右区间的左端点可不可以活,然后统计贡献,左端点不可以存活同理

有些细节太繁琐了,还是自己想想好了

然后讨论区间一共可以活下多少人同理

然后最后统计答案的时候,分类讨论一下最左端点和最右端点的情况统计一下贡献

然后就可以滑稽了


#include<bits/stdc++.h>
using namespace std;
#define N 200010
struct Node{int id,tim;};
bool operator < (Node a,Node b){return a.tim>b.tim;}
int n,m,tot=0;
int u[N],p[N],bel[N]={0},ans,res[N],newpos[N];
bool vis[N];
vector<int> ch[N];
priority_queue<Node> q;
int rt[N],ld[N<<2],rd[N<<2],siz1[N<<2],siz2[N<<2];
int ul[N<<2],ur[N<<2];
bool tmp1[N<<2],tmp2[N<<2];
int tcnt=0;
int st[N];
void pushup(int t){
ul[t]=ul[ld[t]];
ur[t]=ur[rd[t]];
//alive
if(tmp1[ld[t]]){
if(ur[ld[t]]<ul[rd[t]])tmp1[t]=tmp2[rd[t]];
else tmp1[t]=tmp1[rd[t]];
}else tmp1[t]=tmp1[rd[t]]; if(tmp2[ld[t]]){
if(ur[ld[t]]<ul[rd[t]])tmp2[t]=tmp2[rd[t]];
else tmp2[t]=tmp1[rd[t]];
}else tmp2[t]=tmp1[rd[t]];
//siz
if(tmp1[ld[t]]){
if(ur[ld[t]]<ul[rd[t]])siz1[t]=siz1[ld[t]]+siz2[rd[t]];
else siz1[t]=siz1[ld[t]]+siz1[rd[t]]-1;
}else siz1[t]=siz1[ld[t]]+siz1[rd[t]]; if(tmp2[ld[t]]){
if(ur[ld[t]]<ul[rd[t]])siz2[t]=siz2[ld[t]]+siz2[rd[t]];
else siz2[t]=siz2[ld[t]]+siz1[rd[t]]-1;
}else siz2[t]=siz2[ld[t]]+siz1[rd[t]];
}
void build(int &t,int l,int r){
if(l>r)return;
t=++tcnt;
if(l==r){
tmp1[t]=1;tmp2[t]=0;
siz1[t]=1;siz2[t]=0;
ul[t]=ur[t]=u[st[l]];
return;
}
int mid=(l+r)>>1;
build(ld[t],l,mid);
build(rd[t],mid+1,r);
pushup(t);
}
void modify(int t,int l,int r,int pos,int vl){
if(l==r){ul[t]=ur[t]=vl;return;}
int mid=(l+r)>>1;
if(pos<=mid)modify(ld[t],l,mid,pos,vl);
else modify(rd[t],mid+1,r,pos,vl);
pushup(t);
}
void init(int &root,int t){
int now=0;
int u=ch[t][0],tmp=p[u];
st[++now]=u;
newpos[u]=now;
while(tmp!=u){
st[++now]=tmp;
newpos[tmp]=now;
tmp=p[tmp];
}
build(root,1,now);
}
int work(int t){
t=rt[t];
if(ur[t]<ul[t]){
if(tmp2[t])return siz2[t];
else return siz1[t];
}else {
if(tmp1[t])return siz1[t]-1;
else return siz1[t];
}
}
int fa[N],siz;
int findfa(int x){
if(fa[x]==x)return x;
return fa[x]=findfa(fa[x]);
}
int main(){
scanf("%d",&n);
siz=n;
for(int i=1;i<=n;i++)fa[i]=i;
for(int i=1;i<=n;i++){
scanf("%d",&p[i]);
int fi=findfa(i);
int fpi=findfa(p[i]);
if(fi!=fpi)fa[fpi]=fi;
}
for(int i=1;i<=n;i++){
int fi=findfa(i);
if(!bel[fi])bel[i]=bel[fi]=++tot;
else bel[i]=bel[fi];
ch[bel[i]].push_back(i);
}
for(int i=1;i<=n;i++)scanf("%d",&u[i]);
for(int i=1;i<=tot;i++)init(rt[i],i);
int ans=0;
for(int i=1;i<=tot;i++)ans+=work(i);
printf("%d\n",ans);
scanf("%d",&m);
while(m--){
int x,val;
scanf("%d%d",&x,&val);
int f=bel[x];x=newpos[x];
ans-=work(f);
modify(rt[f],1,(signed)ch[f].size(),x,val);
ans+=work(f);
printf("%d\n",ans);
}
return 0;
}

BZOJ4150 AMPPZ2014 The Staging 【线段树】*的更多相关文章

  1. bzoj3932--可持久化线段树

    题目大意: 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的 任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si秒开始,在第 ...

  2. codevs 1082 线段树练习 3(区间维护)

    codevs 1082 线段树练习 3  时间限制: 3 s  空间限制: 128000 KB  题目等级 : 大师 Master 题目描述 Description 给你N个数,有两种操作: 1:给区 ...

  3. codevs 1576 最长上升子序列的线段树优化

    题目:codevs 1576 最长严格上升子序列 链接:http://codevs.cn/problem/1576/ 优化的地方是 1到i-1 中最大的 f[j]值,并且A[j]<A[i] .根 ...

  4. codevs 1080 线段树点修改

    先来介绍一下线段树. 线段树是一个把线段,或者说一个区间储存在二叉树中.如图所示的就是一棵线段树,它维护一个区间的和. 蓝色数字的是线段树的节点在数组中的位置,它表示的区间已经在图上标出,它的值就是这 ...

  5. codevs 1082 线段树区间求和

    codevs 1082 线段树练习3 链接:http://codevs.cn/problem/1082/ sumv是维护求和的线段树,addv是标记这歌节点所在区间还需要加上的值. 我的线段树写法在运 ...

  6. PYOJ 44. 【HNSDFZ2016 #6】可持久化线段树

    #44. [HNSDFZ2016 #6]可持久化线段树 统计 描述 提交 自定义测试 题目描述 现有一序列 AA.您需要写一棵可持久化线段树,以实现如下操作: A v p x:对于版本v的序列,给 A ...

  7. CF719E(线段树+矩阵快速幂)

    题意:给你一个数列a,a[i]表示斐波那契数列的下标为a[i],求区间对应斐波那契数列数字的和,还要求能够维护对区间内所有下标加d的操作 分析:线段树 线段树的每个节点表示(f[i],f[i-1])这 ...

  8. 【BZOJ-3779】重组病毒 LinkCutTree + 线段树 + DFS序

    3779: 重组病毒 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 224  Solved: 95[Submit][Status][Discuss] ...

  9. 【BZOJ-3673&3674】可持久化并查集 可持久化线段树 + 并查集

    3673: 可持久化并查集 by zky Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 1878  Solved: 846[Submit][Status ...

随机推荐

  1. Codeforces Round #365 (Div. 2) E - Mishka and Divisors(转化成01-背包)

    http://codeforces.com/contest/703/problem/E 题意: 给出n个数和一个k,计算出至少要多少个数相乘才是k的倍数. 思路:这道题目参考了杭电大神的代码http: ...

  2. jenkins+gradle打包android遇到的坑

    1.gradle与gradlew的选择 配置project,我们选择gradle进行打包.会看到如下图配置项.然而很多网上教程中给出的选择是第一项.只能这么说,如果你是新建一个androidDemo, ...

  3. Linux权限控制

    文件属性 权限说明 文件用户组调 权限设置建议 文件属性 在shell环境里输入:ls -l 可以查看当前目录文件.如: drwxr-xr-x. 14 root root 4096 Apr 5 18: ...

  4. java23种设计模式之二: 单例设计模式(6种写法)

    目的:在某些业务场景中,我们需要某个类的实例对象的只能有一个,因此我们需要创建一些单例对象. 本文共有6种写法,仅供参考 1.饿汉式 优点: 在多线程情况下,该方法创建的单例是线程安全的(立即加载) ...

  5. C++ substr 和 substring

    功能相似,但参数不同 substr(start,length); substring(start,end);

  6. scrapy 6023 telnet查看爬虫引擎相关状态

    Telnet终端(Telnet Console) Scrapy提供了内置的telnet终端,以供检查,控制Scrapy运行的进程. telnet仅仅是一个运行在Scrapy进程中的普通python终端 ...

  7. ActiveMQ教程(消息发送和接受)

    一 环境的搭建 version为你的版本号 如果你是普通的项目的话,创建一个lib文件夹,导入相应的jar包到你的lib中,jar包为:activemq-all-{version}.jar.log4j ...

  8. laravel中composer镜像服务的方式

    系统全局配置:即将配置信息添加到Composer的全局配置文件config.json中. 单个项目配置:将配置信息添加到某个项目的composer.json文件中. 例1:修改Composer的全局配 ...

  9. matlab eye 函数

    eye(n,n) 产生一个n*n的单位矩阵 eye(n,m) 产生一个n*m的单位矩阵 eye(3,3) ans = 1 0 0 0 1 0 0 0 1 eye(3,4) ans = 1 0 0 0 ...

  10. bfs+状态压缩dp

    题目连接 题解 : 对两两管道进行bfs,然后用dp[i][j] 来表示在i状态下通过了前j个管道 参考博客 #include<bits/stdc++.h> using namespace ...