2015 UESTC 数据结构专题D题 秋实大哥与战争 变化版本的线段树,合并区间,单点查询
D - 秋实大哥与战争
Time Limit: 1 Sec Memory Limit: 256 MB
题目连接
http://acm.uestc.edu.cn/#/contest/show/59Description
男儿何不带吴钩,收取关山五十州。
征战天下是秋实大哥一生的梦想,所以今天他又在练习一个对战游戏。
秋实大哥命令所有士兵从左到右排成了一行来抵挡敌人的攻击。
敌方每一次会攻击一个士兵,这个士兵就会阵亡,整个阵列就会从这个位置断开;同时有的时候已阵亡的士兵会受人赢气息感染而复活。
秋实大哥想知道某一时刻某一个士兵所在的阵列的长度是多少。
Input
第一行包含两个整数n,m,表示秋实大哥的士兵数目和接下来发生的事件数目。
接下来m行,每一行是以下三种事件之一:
0 x : 表示x位置的士兵受到攻击阵亡
1 x : 表示x位置的士兵受人赢气息感染复活
2 x : 秋实大哥想知道第x个士兵所在阵列的长度
1≤n,m≤100000,1≤x≤n。
接下来m行,每一行是以下三种事件之一:
0 x : 表示x位置的士兵受到攻击阵亡
1 x : 表示x位置的士兵受人赢气息感染复活
2 x : 秋实大哥想知道第x个士兵所在阵列的长度
1≤n,m≤100000,1≤x≤n。
Output
对于每一个2 x事件,输出对应的答案占一行。
Sample Input
5 3
2 2
0 3
2 2
2 2
0 3
2 2
Sample Output
5
2
2
HINT
题意
题解:
set或者线段树都行,线段树记录从左边延展的长度,记录从右边延展的长度,和区间最大长度每次更新的时候,就向上更新
代码:
//qscqesze #include <cstdio> #include <cmath> #include <cstring> #include <ctime> #include <iostream> #include <algorithm> #include <set> #include <vector> #include <sstream> #include <queue> #include <typeinfo> #include <fstream> #include <map> #include <stack> typedef long long ll; using namespace std; //freopen("D.in","r",stdin); //freopen("D.out","w",stdout); #define sspeed ios_base::sync_with_stdio(0);cin.tie(0) #define maxn 150001 #define mod 10007 #define eps 1e-9 //const int inf=0x7fffffff; //无限大 const int inf=0x3f3f3f3f; /* int buf[10]; inline void write(int i) { int p = 0;if(i == 0) p++; else while(i) {buf[p++] = i % 10;i /= 10;} for(int j = p-1; j >=0; j--) putchar('0' + buf[j]); printf("\n"); } */ //************************************************************************************** inline ll read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } struct node { int l,r; int len; int lm,rm,mm; }; node a[maxn*4]; void build(int l,int r,int x) { a[x].l=l,a[x].r=r; a[x].lm=a[x].rm=a[x].len=a[x].mm=r-l+1; if(l!=r) { int mid=(l+r)>>1; build(l,mid,x<<1); build(mid+1,r,x<<1|1); } } void updata(int i,int t,int x) { if(a[i].l == a[i].r) { a[i].lm = a[i].rm = a[i].mm = x; return ; } int mid = (a[i].l+a[i].r)>>1; if(t<=mid) updata(2*i,t,x); else updata(2*i+1,t,x); a[i].lm = a[2*i].lm; a[i].rm = a[2*i+1].rm; a[i].mm = max(max(a[2*i].mm,a[2*i+1].mm),a[2*i].rm+a[2*i+1].lm); if(a[2*i].lm == a[2*i].r-a[2*i].l+1) a[i].lm += a[2*i+1].lm; if(a[2*i+1].rm == a[2*i+1].r-a[2*i+1].l+1) a[i].rm += a[2*i].rm; } int query(int x,int p) { if(a[x].l==a[x].r||a[x].mm==0||a[x].mm==a[x].len) return a[x].mm; int mid=(a[x].l+a[x].r)>>1; if(p<=mid) { if(p>=a[x<<1].r-a[x<<1].rm+1) return query(x<<1,p)+query(x<<1|1,mid+1); else return query(x<<1,p); } else { if(p<=a[x<<1|1].l+a[x<<1|1].lm-1) return query(x<<1|1,p)+query(x<<1,mid); else return query(x<<1|1,p); } } int main() { int n,m,x,y; n=read(),m=read(); build(1,n,1); for(int i=0;i<m;i++) { x=read(),y=read(); if(x==0) updata(1,y,0); if(x==1) updata(1,y,1); if(x==2) printf("%d\n",query(1,y)); } }