Gym - 101889D:Daunting device (老司机树)
Posted hua-dong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Gym - 101889D:Daunting device (老司机树)相关的知识,希望对你有一定的参考价值。
题意:N个格子排出一排,开始格子颜色都是1;现在有M个操作:
或,把区间[L,R]颜色改为c;
或,查询一共有多少格子颜色为c。
最后求颜色最多的数量。
数据是随机的,且强制在线。
思路:ODT裸题。维护相同颜色的区间。 split拆分区间,assign操作收缩区间,由于数据随机,区间的个数趋近于log级别。
注意split的时候先split(R+1),再split(L);因为这个我wa20了;在这里有写。 大概就是会改变指针啥的,我对iterator不了解,所以不知道,记下来好了。
这个在大量区间操作的题目中,如果说明了随机的,或者想试一试的情况下,还是非常优秀(暴力)的。
#include<bits/stdc++.h> #define ll long long #define rep(i,a,b) for(int i=a;i<=b;i++) using namespace std; struct in{ int L,R,v; in(){} in(int LL,int RR,int vv):L(LL),R(RR),v(vv){} friend bool operator<(in a,in b){ if(a.L==b.L) return a.R<b.R; return a.L<b.L; } }; set<in>s; #define IT set<in>::iterator int num[100010],ans; IT split(int pos) { IT it=s.lower_bound(in(pos,-2,-2)); if(it!=s.end()&&(*it).L==pos) return it; it--; int l=(*it).L,r=(*it).R,v=(*it).v; s.erase(it); s.insert(in(l,pos-1,v)); return s.insert(in(pos,r,v)).first; } void Assign(int L,int R,int X) { IT it2=split(R+1),it1=split(L); for(IT it=it1;it!=it2;it++) { num[(*it).v]-=((*it).R-(*it).L+1); } s.erase(it1,it2); s.insert(in(L,R,X)); num[X]+=R-L+1; } int main() { int N,L,C,P,X,A,B,S; scanf("%d%d%d",&L,&C,&N); s.insert(in(0,L-1,1)); num[1]=L; rep(i,1,N){ scanf("%d%d%d%d",&P,&X,&A,&B); A%=L; B%=L; S=num[P]%L; int l=(A+1LL*S*S%L)%L,r=(A+1LL*(S+B)*(S+B)%L)%L; Assign(min(l,r),max(l,r),X); } rep(i,1,C) ans=max(ans,num[i]); printf("%d ",ans); return 0; }
以上是关于Gym - 101889D:Daunting device (老司机树)的主要内容,如果未能解决你的问题,请参考以下文章
HIT ACM 2018春 week1 codeforces.com/gym/101652 题解
2019 ICPC Universidad Nacional de Colombia Programming Contest
Gym101522A Gym101522C Gym101522D