• CF817F MEX Queries(线段树上二分)


    题意

    维护一个01串,一开始全部都是0

    3种操作

    1.把一个区间都变为1

    2.把一个区间都变为0

    3.把一个区间的所有数字翻转过来

    每次操作完成之后询问区间最小的0的位置

    l,r<=10^18

    题解

    区间操作想到线段树,离散化不用说,l,r太大了。

    1,2,3操作非常好维护。

    然后在查询中二分查询就好了。

    一开始看别的博客说要加1节点和r+1节点不知道为什么。

    因为我的查询想的是,查询前面全都是1的区间的长度。后来发现做不了。就乖乖照题解做了。

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #include<cmath>
      5 #include<algorithm>
      6 #include<map>
      7 using namespace std;
      8 const long long N=150020;
      9 map<long long,long long> mp;
     10 long long b[N*4],n,m,cnt; 
     11 struct ask{
     12     long long l,r;
     13     long long k;
     14 }q[N];
     15 struct tree{
     16     long long l,r,sum,sev,lazy;
     17 }tr[N*40];
     18 void build(long long l,long long r,long long now){
     19     tr[now].l=l;
     20     tr[now].r=r;
     21     tr[now].lazy=-1;
     22     if(l==r)return;
     23     long long mid=(l+r)>>1;
     24     build(l,mid,now*2);
     25     build(mid+1,r,now*2+1);
     26 }
     27 void pushdown(long long now){
     28     long long mid=(tr[now].l+tr[now].r)>>1;
     29     if(tr[now].lazy!=-1){
     30         tr[now*2].lazy=tr[now*2+1].lazy=tr[now].lazy;
     31         tr[now*2].sum=(mid-tr[now].l+1)*tr[now].lazy;
     32         tr[now*2+1].sum=(tr[now].r-mid)*tr[now].lazy;
     33         tr[now*2].sev=tr[now*2+1].sev=0;
     34         tr[now].lazy=-1; 
     35     }
     36     if(tr[now].sev){
     37         tr[now*2].sev^=1;
     38         tr[now*2+1].sev^=1;
     39         tr[now*2].sum=(mid-tr[now].l+1)-tr[now*2].sum;
     40         tr[now*2+1].sum=(tr[now].r-mid)-tr[now*2+1].sum;
     41         tr[now].sev=0;
     42     }
     43 }
     44 void update(long long l,long long r,long long now,long long k){
     45 //    cout<<l<<" "<<r<<" "<<tr[now].l<<" "<<tr[now].r<<" "<<now<<endl;
     46     pushdown(now);
     47     if(tr[now].l==l&&tr[now].r==r){
     48         tr[now].sum=(tr[now].r-tr[now].l+1)*k;
     49         tr[now].lazy=k;
     50         tr[now].sev=0;
     51         return ;
     52     }
     53     long long mid=(tr[now].l+tr[now].r)>>1;
     54     if(l>mid){
     55         update(l,r,now*2+1,k);
     56     }
     57     else if(r<=mid){
     58         update(l,r,now*2,k);
     59     }
     60     else{
     61         update(l,mid,now*2,k);
     62         update(mid+1,r,now*2+1,k);
     63     }
     64     tr[now].sum=tr[now*2].sum+tr[now*2+1].sum;
     65 }
     66 void serve(long long l,long long r,long long now){
     67     pushdown(now);
     68     if(tr[now].l==l&&tr[now].r==r){
     69         tr[now].sum=(tr[now].r-tr[now].l+1)-tr[now].sum;
     70         tr[now].sev^=1;
     71         return;
     72     }
     73     long long mid=(tr[now].l+tr[now].r)>>1;
     74     if(l>mid)serve(l,r,now*2+1);
     75     else if(r<=mid)serve(l,r,now*2);
     76     else{
     77         serve(l,mid,now*2);
     78         serve(mid+1,r,now*2+1);
     79     }
     80     tr[now].sum=tr[now*2].sum+tr[now*2+1].sum;
     81 }
     82 void check(long long now){
     83     if(tr[now].l==tr[now].r){
     84         printf("%lld
    ",b[tr[now].l]);
     85         return ;
     86     }
     87     long long mid=(tr[now].l+tr[now].r)>>1;
     88     pushdown(now);
     89     if(tr[now*2].sum<mid-tr[now].l+1)check(now*2);
     90     else return check(now*2+1);
     91 }
     92 int main(){
     93     scanf("%lld",&m);
     94     for(long long i=1;i<=m;i++){
     95         scanf("%lld%lld%lld",&q[i].k,&q[i].l,&q[i].r);
     96         q[i].r++;
     97         b[++cnt]=q[i].l;
     98         b[++cnt]=q[i].r;
     99     }
    100     b[++cnt]=1;
    101     sort(b+1,b+1+cnt);
    102     n=unique(b+1,b+1+cnt)-(b+1);
    103     for(long long i=1;i<=n;i++){
    104         mp[b[i]]=i;
    105     }
    106     build(1,n,1);
    107     for(long long i=1;i<=m;i++){
    108         if(q[i].k==1){
    109             update(mp[q[i].l],mp[q[i].r]-1,1,1);
    110         }
    111         else if(q[i].k==2){
    112             update(mp[q[i].l],mp[q[i].r]-1,1,0);
    113         }
    114         else{
    115             serve(mp[q[i].l],mp[q[i].r]-1,1);
    116         }
    117         check(1);
    118     }
    119     return 0;
    120 }
    View Code
  • 相关阅读:
    Oracle SGA详解
    oracle如何保证读一致性 第一弹
    Make命令完全详解教程
    ProC第三弹
    ProC第一弹
    ProC第二弹
    $(MAKE) , make命令
    转:跟我一起写Makefile (PDF重制版)
    [bzoj1105][POI2007]石头花园SKA
    可并堆学习
  • 原文地址:https://www.cnblogs.com/Xu-daxia/p/9397803.html
Copyright © 2020-2023  润新知