【JZOJ 4603】颜料大乱斗

来源:互联网 发布:mac淘宝助手官方下载 编辑:程序博客网 时间:2024/04/26 01:27

Description

画师傅又要开始画画了,这次他花了三天三夜将一堵墙涂成了白色。
但是画师傅有个顽劣的弟子小花,小花讨厌画师傅对Ta始乱终弃,所以趁 画师傅不在用不同的颜料将墙涂来涂去。
然而画师傅为了保护他的大作,设置了一个监控机制A。A每隔一段时间会 查珣某一段墙上的颜料的种类数,并将其记录下来。
现在画师傅回来了,看到五颜六色色彩斑斓灯火阑珊金碧辉煌的【哗】墙, 一口气没换上来,卒。
作为画师傅的好友杀小姐的你,为了追查画师傅的死因,于是调用了墙的监 控机制A的记录。于是,你看到了怎样的记录呢?

Solution

很显然,开30棵线段树即可,
但是:
有可能l>r啊!!!
白色是1啊!!!
复杂度:O(n30log(n))
要优化常数。

Code

#include<iostream>#include<cstdio>#include<cstdlib>#define fo(i,a,b) for(int i=a;i<=b;i++) using namespace std;const int N=100500;int read(int &n){    char ch=' ';int q=0,w=1;    for(;(ch!='-')&&((ch<'0')||(ch>'9'));ch=getchar());    if(ch=='-')w=-1,ch=getchar();    for(;ch>='0' && ch<='9';ch=getchar())q=q*10+ch-48;n=q*w;return n;}int n,m,ans;int b[N*3][32],la[N*3];int s[32];void doit(int l,int r,int e){    if(!la[e])return;    fo(i,0,m)b[e][i]=0;    b[e][la[e]]=r-l+1;    if(l!=r)la[e*2]=la[e],la[e*2+1]=la[e];    la[e]=0;}void build(int l,int r,int e){    if(l==r)    {        b[e][1]=1;        return;    }    int t=(l+r)/2;    build(l,t,e*2);    build(t+1,r,e*2+1);    b[e][1]=r-l+1;}void change(int l,int r,int e,int l1,int r1,int l2){    if(l==l1&&r==r1)    {        la[e]=l2;        doit(l,r,e);        return;    }    int t=(l+r)/2;    doit(l,t,e*2),doit(t+1,r,e*2+1);    if(r1<=t)change(l,t,e*2,l1,r1,l2);        else if(t<l1)change(t+1,r,e*2+1,l1,r1,l2);            else change(l,t,e*2,l1,t,l2),change(t+1,r,e*2+1,t+1,r1,l2);    fo(i,0,m)b[e][i]=b[e*2][i]+b[e*2+1][i];}void find(int l,int r,int e,int l1,int r1){    doit(l,r,e);    if(l==l1&&r==r1)    {        fo(i,0,m)s[i]+=b[e][i];        return;    }    int t=(l+r)/2;    if(r1<=t)find(l,t,e*2,l1,r1);        else if(t<l1)find(t+1,r,e*2+1,l1,r1);            else find(l,t,e*2,l1,t),find(t+1,r,e*2+1,t+1,r1);}int main(){    int q,l,r,m_;    read(n),read(m),read(m_);    build(1,n,1);    while(m_--)    {        char ch=' ';        while(ch!='P'&&ch!='C')ch=getchar();        read(l),read(r);        if(r<l)swap(l,r);        if(ch=='C')        {            read(q);            change(1,n,1,l,r,q);        }        else         {            ans=q=0;            fo(i,0,m)s[i]=0;            find(1,n,1,l,r);            fo(i,1,m)if(s[i])ans++,q+=s[i];            printf("%d\n",ans+(q<r-l+1));        }    }    return 0;}
0 0
原创粉丝点击