12.06

luoguP5445 [APIO2019]路灯 树套树+set

 

code: 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include <vector>
#include <cstdio> 
#include <cstring>
#include <map>
#include <set>
#include <algorithm> 
#define N 300005
#define MAX 320005 
#define setIO(s) freopen(s".in","r",stdin) ,freopen(s".out","w",stdout)    
using namespace std;   
int n;         
int rt[MAX];           
namespace tr {
    #define lson s[x].ls
    #define rson s[x].rs       
    int tot; 
    int newnode() { return ++tot; }   
    int lowbit(int x) { return x&(-x); }  
    struct node {
        int ls,rs,sum;   
    }s[MAX*100];     
    void update(int &x,int l,int r,int p,int v)
    {  
        if(!x) x=newnode();  
        s[x].sum+=v;   
        if(l==r) return;
        int mid=(l+r)>>1;
        if(p<=mid) update(lson,l,mid,p,v);
        else update(rson,mid+1,r,p,v);  
    }
    int query(int x,int l,int r,int L,int R)
    {
        if(!x) return 0;
        if(l>=L&&r<=R) return s[x].sum;  
        int mid=(l+r)>>1,re=0;   
        if(L<=mid) re+=query(lson,l,mid,L,R);
        if(R>mid)  re+=query(rson,mid+1,r,L,R);     
        return re;  
    }   
    void upd(int x,int y,int v)
    {
        for(int i=x;i<=N;i+=lowbit(i))
            update(rt[i],1,N,y,v);    
    }
    int que(int x,int y)
    {
        int re=0;
        for(int i=x;i;i-=lowbit(i))
            re+=query(rt[i],1,N,1,y);   
        return re;  
    }
    #undef lson
    #undef rson
}; 
char str[MAX]; 
// 断点在 i->i+1  
set<int>S;  
set<int>::iterator it;  
int Q,T,swi[N];    
void con(int x,int y)
{       
    it=S.lower_bound(x);    
    int l,r,L,R; 
    if(it==S.begin()) l=1,r=x;    
    else --it,l=(*it)+1,r=x;       
    it=S.lower_bound(x);   
    it++; 
    if(it==S.end()) L=x+1,R=n+1;   
    else L=x+1,R=(*it);       
    S.erase(x);              
    tr::upd(l,L,Q-T);        
    tr::upd(l,R+1,T-Q);  
    tr::upd(r+1,L,T-Q);    
    tr::upd(r+1,R+1,Q-T);   
void clo(int x,int y)
{     
    // printf("%d %d\n",x,y); 
    S.insert(x);  
    it=S.lower_bound(x);  
    int l,r,L,R;                
    if(it==S.begin()) l=1,r=x;  
    else --it,l=(*it)+1,r=x;  
    it=S.lower_bound(x);    
    it++;  
    if(it==S.end()) L=x+1,R=n+1;  
    else L=x+1,R=(*it);         
    tr::upd(l,L,T-Q);   
    tr::upd(l,R+1,Q-T);  
    tr::upd(r+1,L,Q-T);          
    tr::upd(r+1,R+1,T-Q);    
}
int ask(int x,int y)
{          
    int re=tr::que(x,y);   
    set<int>::iterator X,Y;       
    X=S.lower_bound(x);
    Y=S.lower_bound(y);   
    if(X==Y) re-=Q-T;
    return re;   
}  
int main() {
    // setIO("input");   
    int i,j;        
    scanf("%d%d%s",&n,&Q,str+1);             
    // t=0  
    for(i=1;i<=n;++i) S.insert(i);                
    for(i=1;i<=n;++i) if(str[i]=='1') con(i,i+1),swi[i]=1;   
    for(T=1;T<=Q;++T)
    {
        scanf("%s",str);
        if(str[0]=='t')
        {
            int x;
            scanf("%d",&x); 
            if(swi[x]) clo(x,x+1);
            else con(x,x+1); 
            swi[x]^=1;
        }
        else
        {
            int x,y;
            scanf("%d%d",&x,&y);  
            printf("%d\n",ask(x,y));
        }
    }    
    return 0;
}
posted @   liuxuechao  阅读(1)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示