1. 程式人生 > >Gym - 101889D:Daunting device (老司機樹)

Gym - 101889D:Daunting device (老司機樹)

都是 esp \n sig hang print scan include pos

題意: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\n",ans); return 0; }

Gym - 101889D:Daunting device (老司機樹)