Physical Education Lessons Codeforces - 915E

http://codeforces.com/problemset/problem/915/E

大概有几种思路:

1.动态开点线段树+标记下传

#1.1标记永久化:想了一会没想出来

1.2可以先扫一遍询问把所有需要的点建出来,然后pushdown就不管没建出来的点了,空间跟标记永久化一样

2.离散化+线段树

3.用splay维护区间(估计没人愿意去写)

4.用一个set<pair<int,int>>记所有非工作日(或工作日)区间,修改就暴力找到相关的区间去改

由于每一次操作最多多出O(1)个区间,因此尽管有时会一次删掉多个区间,但复杂度是对的

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<set>
 4 #define fi first
 5 #define se second
 6 using namespace std;
 7 typedef pair<int,int> P;
 8 set<P> s;
 9 set<P>::iterator it;
10 int ans,n,q;
11 int main()
12 {
13     int i,idx,l,r;P t;
14     scanf("%d%d",&n,&q);ans=n;s.insert(P(n,1));
15     while(q--)
16     {
17         scanf("%d%d%d",&l,&r,&idx);
18         it=s.lower_bound(P(l,0));
19         if(it!=s.end()&&it->se<=l)
20         {
21             t=*it;s.erase(it);
22             if(l!=t.se)    s.insert(P(l-1,t.se));
23             s.insert(P(t.fi,l));
24         }
25         it=s.lower_bound(P(r,0));
26         if(it!=s.end()&&it->se<=r)
27         {
28             t=*it;s.erase(it);
29             if(t.fi!=r)    s.insert(P(t.fi,r+1));
30             s.insert(P(r,t.se));
31         }
32         for(it=s.lower_bound(P(l,0));it!=s.end()&&it->fi<=r;it=s.lower_bound(P(l,0)))
33             ans-=it->fi-it->se+1,s.erase(it);
34         if(idx==2)    s.insert(P(r,l)),ans+=r-l+1;
35         printf("%d\n",ans);
36     }
37     return 0;
38 }

 

posted @ 2018-05-11 18:29  hehe_54321  阅读(202)  评论(0编辑  收藏  举报
AmazingCounters.com