zoukankan      html  css  js  c++  java
  • [Ynoi2018] 五彩斑斓的世界

    由乃OI的卡常题......

    CF896E Welcome home, Chtholly 传送门

    洛谷 CF896E 传送门

    以上两个传送门是CF上的,3000ms、512Mb。

    这个 洛谷 P4117 [Ynoi2018]五彩斑斓的世界 是1000ms、128Mb(卡常+卡空间)。

    这道题的修改操作很特殊,是对区间内某些拥有特殊性质的数进行操作。

    各种数据结构无法满足这个要求,所以我们考虑分块。

    把块内值相等的数用并查集连到一起,每个值记录一个head就行了。

    但是如果块内全是大于x的数,我们需要对所有的head进行操作,复杂度太高了。

    所以如果有一半以上都是大于x的,考虑将不大于x的都加上x,再打个标记让整个块减少x就行了。

    其实时间空间也不是太卡,稍微搞一搞就能过了。

      1 #include<cstdio>
      2 #include<cmath>
      3 #include<algorithm>
      4 
      5 using std::max;
      6 using std::min;
      7 typedef unsigned int ui;
      8 
      9 ui n,m,sz;
     10 ui v[100001],hv[100001];
     11 ui f[100001],hd[225][100001];
     12 ui l[225],r[225],cnt[100001];
     13 ui bl[100001],mx[225],lz[225];
     14 
     15 ui read()
     16 {
     17     char c=getchar();ui ret=0u;
     18     while(c<'0'||c>'9')c=getchar();
     19     while(c>='0'&&c<='9')ret=ret*10u+c-'0',c=getchar();
     20     return ret;
     21 }
     22 
     23 void getmx(ui id)
     24 {
     25     while(!hd[id][mx[id]])mx[id]--;
     26 }
     27 
     28 ui fin,bef;
     29 
     30 ui fa(ui p)
     31 {
     32     fin=p;
     33     while(fin^f[fin])fin=f[fin];
     34     while(f[p]^fin)bef=p,p=f[p],f[bef]=fin;
     35     return fin;
     36 }
     37 
     38 void reset(ui id)
     39 {
     40     ui i;
     41     for(i=l[id];i<=r[id];i++)v[i]=hv[fa(i)],hd[id][v[i]]=0u;
     42     for(i=l[id];i<=r[id];i++)f[i]=i,cnt[i]=1u;
     43     for(i=l[id];i<=r[id];i++)
     44     {
     45         if(hd[id][v[i]])
     46             f[i]=hd[id][v[i]],cnt[hd[id][v[i]]]+=cnt[i];
     47         else
     48             hd[id][v[i]]=i,hv[i]=v[i];
     49     }
     50     getmx(id);
     51 }
     52 
     53 void change(ui id,ui lb,ui rb,ui x)
     54 {
     55     ui i;
     56     for(i=l[id];i<=r[id];i++)v[i]=hv[fa(i)];
     57     for(i=l[id];i<=r[id];i++)hd[id][v[i]]=0u;
     58     for(i=lb;i<=rb;i++)if(v[i]-lz[id]>x)v[i]-=x;
     59     for(i=l[id];i<=r[id];i++)f[i]=i,hv[i]=v[i];
     60     reset(id);
     61 }
     62 
     63 int main()
     64 {
     65     n=read(),m=read();sz=(ui)(sqrt(2*n));
     66     ui i,j;ui *fr,*to;
     67     for(i=1u;i<=n;i++){bl[i]=(i-1u)/sz+1u;f[i]=i;}
     68     for(i=1u;i<=bl[n];i++){l[i]=(i-1u)*sz+1u;r[i]=min(n,i*sz);}
     69     for(i=1u;i<=n;i++)
     70         {v[i]=hv[i]=read();mx[bl[i]]=max(mx[bl[i]],v[i]);}
     71     for(i=1u;i<=bl[n];i++)reset(i);
     72     ui op,lb,rb,x;
     73     while(m--)
     74     {
     75         op=read(),lb=read(),rb=read(),x=read();
     76         if(op==1u)
     77         {
     78             if(bl[lb]==bl[rb])
     79             {
     80                 change(bl[lb],lb,rb,x);
     81                 continue;
     82             }
     83             change(bl[lb],lb,r[bl[lb]],x);
     84             change(bl[rb],l[bl[rb]],rb,x);
     85             for(i=bl[lb]+1u;i<bl[rb];i++)
     86             {
     87                 if((x<<1)>mx[i]-lz[i])
     88                 {
     89                     for(j=x+lz[i]+1u;j<=mx[i];j++)
     90                     {
     91                         fr=&hd[i][j],to=&hd[i][j-x];
     92                         if(!(*fr))continue;
     93                         if(*to){cnt[*to]+=cnt[*fr];f[*fr]=*to;}
     94                         else{(*to)=(*fr);hv[*to]=j-x;}
     95                         *fr=0u;
     96                     }
     97                     getmx(i);
     98                 }
     99                 else
    100                 {
    101                     for(j=lz[i]+1u;j<=x+lz[i];j++)
    102                     {
    103                         fr=&hd[i][j],to=&hd[i][j+x];
    104                         if(!(*fr))continue;
    105                         if(*to){cnt[*to]+=cnt[*fr];f[*fr]=*to;}
    106                         else{(*to)=(*fr);hv[*to]=j+x;}
    107                         *fr=0u;
    108                     }
    109                     lz[i]+=x;
    110                 }
    111             }
    112         }
    113         if(op==2u)
    114         {
    115             ui ans=0u;
    116             if(bl[lb]==bl[rb])
    117             {
    118                 for(i=lb;i<=rb;i++)
    119                     if(hv[fa(i)]==x+lz[bl[lb]])ans++;
    120                 printf("%u
    ",ans);
    121                 continue;
    122             }
    123             for(i=lb;i<=r[bl[lb]];i++)
    124                 if(hv[fa(i)]==x+lz[bl[lb]])ans++;
    125             for(i=l[bl[rb]];i<=rb;i++)
    126                 if(hv[fa(i)]==x+lz[bl[rb]])ans++;
    127             for(i=bl[lb]+1u;i<bl[rb];i++)
    128                 if(x+lz[i]<=100000u)ans+=cnt[hd[i][x+lz[i]]];
    129             printf("%u
    ",ans);
    130         }
    131     }
    132     return 0;
    133 }
  • 相关阅读:
    SQLSERVER排查CPU占用高的情况
    SQLSERVER排查CPU占用高的情况
    查看SQL SERVER数据库的连接数
    查看SQL SERVER数据库的连接数
    SQL Server 运行状况监控SQL语句
    SQL Server 运行状况监控SQL语句
    Java8高阶函数及判断高阶函数的方式
    Java8高阶函数及判断高阶函数的方式
    mybatis中association和collection的column传入多个参数问题
    mybatis中association和collection的column传入多个参数问题
  • 原文地址:https://www.cnblogs.com/cervusy/p/9990759.html
Copyright © 2011-2022 走看看