Description
Input
第一行由一个空格隔开的两个正整数 m, c,意义见题目描述。
接下来 m 行,每行可能有以下形式:
construct l r v 代表发生了第一种事件;
destruct l r 代表发生了第二种事件;
query x 代表发生了第三种事件。
接下来 m 行,每行可能有以下形式:
construct l r v 代表发生了第一种事件;
destruct l r 代表发生了第二种事件;
query x 代表发生了第三种事件。
Output
对于每个 query 操作,请输出一行一个整数代表此时坐标 x 处的信号强度。
Sample Input
11 10000 query 5 construct 5 500 100 query 500 query 1000 construct 10 90 5 query 44 destruct 44 66 query 55 construct 50 60 3 query 46 query 6000
Sample Output
0 975 0 9999 9775 9984 0
Data Constraint
题解
- c++有c++的优势,这题可以用c++里STL库里的set来做(平衡树)
- 每次可以将形如(l,r,v)的一个三元组插入set
- 但是,可以发现对于下面的操作的话,l和r都有信号站会更好处理,所以把r定到最后一个信号站的位置
- 对于插入操作,我们发现,当前插入的区间,可以会被之前插入的区间所包含,那么就会把一个区间分成两个部分
- 因为题目保证插入操作[l,r]中没有型号站,那么如果被包含的话
- 就一定可以把大区间分成两个区间,至于分出来的区间的左右坐标也要满足l和r都有信号站
- 那么就会分成[B.l,S.l-1-(S.l-1-B.l)%B.v]和[S.r+1+(B.r-S.r-1)%B.v,B.r]
- 对于删除操作,也就是把与[l,r]区间相交的区间都要分出不在[l,r]区间的部分
- 那么就一共有四种情况:
- ①一个区间的左边和[l,r]相交
- ②一个区间的右边和[l,r]相交
- ③一个区间包含[l,r]
- ④[l,r]包含一个区间
- 注意,还是要满足区间的左右区间都是信号站
- 对于查询操作,就是找到x向左右区间延伸的第一个l和r,和跨过x的区间
- 这题主要就是一道考验细节的题目了
代码
1 #include <cstdio> 2 #include <iostream> 3 #include <set> 4 using namespace std; 5 struct edge { int l,r,v; }a,b,t; 6 struct cmp { bool operator()(const edge &a,const edge &b) { return a.l<b.l; } }; 7 int m,ans,inf=1000000010; 8 long long c,tot; 9 char str[10]; 10 set<edge,cmp>Q; 11 int main() 12 { 13 freopen("cellphone.in","r",stdin); 14 freopen("cellphone.out","w",stdout); 15 scanf("%d%lld",&m,&c); 16 for(int i=1;i<=m;i++) 17 { 18 scanf("%s",str); 19 if (str[0]=='c') 20 { 21 scanf("%d%d%d",&a.l,&a.r,&a.v); 22 a.r=a.r-(a.r-a.l)%a.v; b=a; 23 set<edge,cmp>::iterator k=Q.lower_bound(b); 24 if (k!=Q.begin()) 25 { 26 k--;b=*k; 27 if (b.r>=a.l) 28 { 29 Q.erase(k); 30 t=b; t.r=a.l-1-(a.l-1-t.l)%t.v; Q.insert(t); 31 t=b; t.l=a.r+1+(t.r-a.r-1)%t.v; Q.insert(t); 32 } 33 } 34 Q.insert(a); 35 } 36 if (str[0]=='d') 37 { 38 scanf("%d%d",&a.l,&a.r); 39 set<edge,cmp>::iterator k=Q.lower_bound(a); 40 set<edge,cmp>::iterator p; 41 if (k!=Q.begin()) 42 { 43 k--;p=k++;b=*p; 44 if (b.r>=a.l) 45 { 46 Q.erase(p); 47 t=b; t.r=a.l-1-(a.l-1-t.l)%t.v; Q.insert(t); 48 if (b.r>a.r) 49 { 50 t=b; t.l=a.r+1+(t.r-a.r-1)%t.v; Q.insert(t); 51 continue; 52 } 53 } 54 } 55 b=*k; 56 for (;k!=Q.end()&&b.l<=a.r;) 57 { 58 p=k++; Q.erase(p); 59 if (b.r>a.r) 60 { 61 b.l=a.r+1+(b.r-a.r-1)%b.v; Q.insert(b); 62 break; 63 } 64 b=*k; 65 } 66 } 67 if (str[0]=='q') 68 { 69 scanf("%d",&a.l); 70 if (Q.empty()) { printf("0\n"); continue; } 71 set<edge,cmp>::iterator k=Q.lower_bound(a); 72 ans=inf; 73 if (k!=Q.end()) b=*k,ans=b.l-a.l; 74 if (k!=Q.begin()) k--; 75 b=*k; 76 if (b.l<=a.l) 77 { 78 if (b.r<=a.l) ans=min(ans,a.l-b.r); 79 else ans=min(ans,min((a.l-b.l)%b.v,(b.r-a.l)%b.v)); 80 } 81 printf("%lld\n",(c-1ll*ans*1ll*ans)>0?(c-1ll*ans*1ll*ans):0); 82 } 83 } 84 return 0; 85 }