string [segment tree to optimize the tub exhaust]

Probably meaning of the questions is to give you a string, 1e5 revision, each time to a range of ascending or descending order, the final output of the string;

Is actually a pretty bare tree line optimization problem; but I do not have awareness to combine barrel row, rushed to the .....

First algorithm 1.40 points

O (NMlogN)

 1 inline void update(int k){
 2     for(int i=1;i<=26;++i){
 3         tmp[k].tong[i]=tmp[ls].tong[i]+tmp[rs].tong[i];
 4     }
 5 }
 6 
 7 void ud(int k,int l,int r,int L,int R){
 8     if(L<=l&&r<=R)return void();
 9     if(L<=mid)ud(ls,l,mid,L,R);
10     if(R>mid)ud(rs,mid+1,r,L,R);
11     update(k);
12

Direct sort

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define val(x) (x-'a'+1)
 4 int s[100050],N,M;
 5 char S[100050];
 6 bool cmp1(int a,int b){return a<b;}
 7 bool cmp0(int a,int b){return a>b;}
 8 int main()
 9 {
10     //freopen("da.in","r",stdin);
11    // freopen("ac.out","w",stdout);
12     scanf("%d%d",&N,&M);
13     scanf("%s",S+1);
14     for(int i=1;i<=N;++i)s[i]=val(S[i]);
15     for(int i=1,l,r,opt;i<=M;++i){
16         scanf("%d%d%d",&l,&r,&opt);
17         if(!opt)sort(s+l,s+r+1,cmp0);
18         else sort(s+l,s+r+1,cmp1);
19        // if(clock()>999900)break;
20     }
21     char c;
22     for(int i=1;i<=N;++i){
23         c=s[i]+'a'-1;
24         printf("%c",c);
25     }
26     printf("\n");
27 }

2. Secondly, the algorithm is still 40 points:

In fact, the topic is ungrateful people, we can directly barrels row, complexity O (NM); at least down a log, but still 40 points;

Code is not provided;

Finally 3.100 points algorithm:

Idea: combine in row 2. barrels idea, we found that one can only change the sorting O (N) complexity, and N, M <= 1e5, naturally think of tree line optimization barrels row;

And think of the complexity of the bare idea is O (MNlogN) calcium oxide! As with violence!

But you can find a range of values ​​N is your letter, that only 26 N friends;

Finally, O (MlogN * 26)

Analyze M is asking; logN is the tree line query (merger barrels and buckets you need to query the modified region to synthesize a new bucket); 26 is required for each barrel merge complexity;

Well, then, every time we modify a range of sorts, the corresponding section of the barrel is to be merged into a new bucket, and then modify with this new range of barrels, but note that this section must not be modified to really O (N) interval assignment

It would become a real O (NMlogN) a;

How to do that?

We can play tag lazy ah! Do not say you do not like me, marking ......

Then we can mark which sections were modified and then again down access to it, the last time dfs down to a full statistical answer to it;

Note down here very long

 1 void down(int k){
 2     if(!tmp[k].lazy)return ;
 3     register int sz=len(ls),pl=0,pr=0;
 4     memset(tmp[ls].tong,0,sizeof(tmp[ls].tong));
 5     memset(tmp[rs].tong,0,sizeof(tmp[rs].tong));
 6     if(tmp[k].opt){
 7         for(int i=1;i<=26;++i){
 8             if(tmp[k].tong[i]<=sz)
 9             {
10                 tmp[ls].tong[i]=tmp[k].tong[i],sz-=tmp[k].tong[i];
11             }
12             else {
13                 tmp[ls].tong[i]=sz;sz=i;break;
14             }
15         }
16         tmp[rs].tong[sz]=tmp[k].tong[sz]-tmp[ls].tong[sz];
17         if(len(rs)==1&&tmp[rs].tong[sz]==1){pr=sz;}
18         register int zs=len(rs)-tmp[rs].tong[sz];
19         for(int i=sz+1;i<=26;++i){
20             tmp[rs].tong[i]=tmp[k].tong[i];
21             zs-=tmp[k].tong[i];
22             if(!zs)break;
23         }
24     }
25     else {
26         for(int i=26;i>=1;--i){
27             if(tmp[k].tong[i]<=sz)
28             {
29                 tmp[ls].tong[i]=tmp[k].tong[i],sz-=tmp[k].tong[i];
30             }
31             else {
32                 tmp[ls].tong[i]=sz;sz=i;break;
33             }
34         }
35         tmp[rs].tong[sz]=tmp[k].tong[sz]-tmp[ls].tong[sz];
36         register int zs=len(rs)-tmp[rs].tong[sz];
37         for(int i=sz-1;i>=1;--i){
38             tmp[rs].tong[i]=tmp[k].tong[i];
39             zs-=tmp[k].tong[i];
40             if(!zs)break;
41         }
42     }
43     if(tmp[ls].l!=tmp[ls].r)tmp[ls].lazy=1;
44     else tmp[ls].lz=pl;tmp[ls].opt=tmp[k].opt;
45     if(tmp[rs].l!=tmp[rs].r)tmp[rs].lazy=1;
46     else tmp[rs].lz=pr;tmp[rs].opt=tmp[k].opt;
47     tmp[k].lazy=0;tmp[k].opt=0;
48 }

Of course, I'm not a Deepin the same indent;

In fact, down here, it is to segment your tree this node's two sons, the process of re-assignment barrel range corresponds, of course, once the assignment requires O (52);

Tip:

Another point is particularly prone to error

Remember that after you every time interval corresponding to the modified merger to be modified barrel barrel the corresponding section (section modification) immediately :( lg here this vector is stored in the segment tree you change the interval node number)

 1 void exch(int opt){
 2     sort(lg.begin(),lg.end(),cmp);
 3     for(int i=0,sz,tt=1,ts=26;i<lg.size();++i){
 4         sz=len(lg[i]);
 5         memset(tmp[lg[i]].tong,0,sizeof(tmp[lg[i]].tong));
 6         if(opt){
 7             for(;tt<=26;++tt){
 8             if(sz>=ans[tt]){
 9                 sz-=ans[tt];
10                 tmp[lg[i]].tong[tt]=ans[tt];
11             }
12             else {
13                 tmp[lg[i]].tong[tt]=sz;
14                 ans[tt]-=sz;break;
15             }
16             }
17         }
18         else {
19             for(;ts>=1;--ts){
20                         if(sz>=ans[ts]){
21                             sz-=ans[ts];
22                             tmp[lg[i]].tong[ts]=ans[ts];
23                         }
24                         else {
25                             tmp[lg[i]].tong[ts]=sz;
26                             ans[ts]-=sz;break;
27                         }
28             }
29         }
30     }
31 }
Interval modification

Then immediately after you modify those changes to the root zone update again, after all, you can only maintain the lazy mark son not maintain his father;

 1 inline void update(int k){
 2     for(int i=1;i<=26;++i){
 3         tmp[k].tong[i]=tmp[ls].tong[i]+tmp[rs].tong[i];
 4     }
 5 }
 6 
 7 
 8 void ud(int k,int l,int r,int L,int R){
 9     if(L<=l&&r<=R)return void();
10     if(L<=mid)ud(ls,l,mid,L,R);
11     if(R>mid)ud(rs,mid+1,r,L,R);
12     update(k);
13 }
update

Then attach the code

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define val(x) (x-'a'+1)
  4 #define mid (l+r>>1)
  5 #define ls (k<<1)
  6 #define rs (k<<1|1)
  7 #define len(x) (tmp[x].r-tmp[x].l+1)
  8 int s[100050],N,M;
  9 char S[100050];
 10 struct node{
 11    int l;int r;
 12    int tong[30];
 13    int lazy,lz,opt;
 14 }tmp[100050<<3];
 15 int ans[30];
 16 vector<int>lg;
 17 
 18 inline void update(int k){
 19     for(int i=1;i<=26;++i){
 20         tmp[k].tong[i]=tmp[ls].tong[i]+tmp[rs].tong[i];
 21     }
 22 }
 23 
 24 void down(int k){
 25     if(!tmp[k].lazy)return ;
 26     register int sz=len(ls),pl=0,pr=0;
 27     memset(tmp[ls].tong,0,sizeof(tmp[ls].tong));
 28     memset(tmp[rs].tong,0,sizeof(tmp[rs].tong));
 29     if(tmp[k].opt){
 30         for(int i=1;i<=26;++i){
 31             if(tmp[k].tong[i]<=sz)
 32             {
 33                 tmp[ls].tong[i]=tmp[k].tong[i],sz-=tmp[k].tong[i];
 34            //     if(len(ls)==1&&tmp[ls].tong[i]){pl=i;break;}
 35             }
 36             else {
 37                 tmp[ls].tong[i]=sz;sz=i;break;
 38             }
 39         }
 40         //for(int i=1;i<=sz-1;++i)tmp[rs].tong[i]=0;
 41         //for(int i=sz+1;i<=26;++i)tmp[ls].tong[i]=0;
 42         tmp[rs].tong[sz]=tmp[k].tong[sz]-tmp[ls].tong[sz];
 43         if(len(rs)==1&&tmp[rs].tong[sz]==1){pr=sz;}
 44         register int zs=len(rs)-tmp[rs].tong[sz];
 45         for(int i=sz+1;i<=26;++i){
 46             tmp[rs].tong[i]=tmp[k].tong[i];
 47             zs-=tmp[k].tong[i];
 48             if(!zs)break;
 49         //    if(len(rs)==1&&tmp[rs].tong[i]&&!pr)pr=i;
 50         }
 51     }
 52     else {
 53         for(int i=26;i>=1;--i){
 54             if(tmp[k].tong[i]<=sz)
 55             {
 56                 tmp[ls].tong[i]=tmp[k].tong[i],sz-=tmp[k].tong[i];
 57                // if(len(ls)==1&&tmp[ls].tong[i]){pl=i;break;}
 58             }
 59             else {
 60                 tmp[ls].tong[i]=sz;sz=i;break;
 61             }
 62         }
 63         //for(int i=26;i>=sz+1;--i)tmp[rs].tong[i]=0;
 64         //for(int i=1;i<=sz-1;++i)tmp[ls].tong[i]=0;
 65         tmp[rs].tong[sz]=tmp[k].tong[sz]-tmp[ls].tong[sz];
 66         //if(len(rs)==1&&tmp[rs].tong[sz]==1){pr=sz;}
 67         register int zs=len(rs)-tmp[rs].tong[sz];
 68         for(int i=sz-1;i>=1;--i){
 69             tmp[rs].tong[i]=tmp[k].tong[i];
 70             zs-=tmp[k].tong[i];
 71             if(!zs)break;
 72           //  if(len(rs)==1&&tmp[rs].tong[i]&&!pr)pr=i;
 73         }
 74     }
 75     if(tmp[ls].l!=tmp[ls].r)tmp[ls].lazy=1;
 76     else tmp[ls].lz=pl;tmp[ls].opt=tmp[k].opt;
 77     if(tmp[rs].l!=tmp[rs].r)tmp[rs].lazy=1;
 78     else tmp[rs].lz=pr;tmp[rs].opt=tmp[k].opt;
 79     tmp[k].lazy=0;tmp[k].opt=0;
 80 }
 81 
 82 inline void merge(int u,int opt){
 83     down(u);
 84     for(register int i=1;i<=26;++i){
 85         ans[i]+=tmp[u].tong[i];
 86     }
 87     if(len(u)>1)tmp[u].lazy=1;lg.push_back(u);
 88     tmp[u].opt=opt;
 89 }
 90 
 91 inline int zip(int k){
 92     //cout<<"laidao!"<<endl;
 93     for(int i=1;i<=26;++i)if(tmp[k].tong[i])return i;
 94 }
 95 
 96 void find(int k,int l,int r){
 97     if(l==r)return s[l]=zip(k),void();
 98     down(k);
 99     find(ls,l,mid);
100     find(rs,mid+1,r);
101 }
102 
103 void query(int k,int l,int r,int L,int R,int opt){
104     if(L<=l&&r<=R)return merge(k,opt),void();
105     down(k);
106     if(L<=mid)query(ls,l,mid,L,R,opt);
107     if(R>mid)query(rs,mid+1,r,L,R,opt);
108 }
109 
110 void ud(int k,int l,int r,int L,int R){
111     if(L<=l&&r<=R)return void();
112     if(L<=mid)ud(ls,l,mid,L,R);
113     if(R>mid)ud(rs,mid+1,r,L,R);
114     update(k);
115 }
116 
117 void building(int k,int l,int r){
118     tmp[k].l=l;tmp[k].r=r;
119     if(l==r)return  tmp[k].l=tmp[k].r=l,tmp[k].tong[s[l]]=1,tmp[k].lazy=tmp[k].opt=0,void();
120     building(ls,l,mid);building(rs,mid+1,r);
121     update(k);
122 }
123 
124 bool cmp(int u,int v){return tmp[u].l<tmp[v].l;}
125 
126 void exch(int opt){
127     sort(lg.begin(),lg.end(),cmp);
128     for(int i=0,sz,tt=1,ts=26;i<lg.size();++i){
129         sz=len(lg[i]);
130         memset(tmp[lg[i]].tong,0,sizeof(tmp[lg[i]].tong));
131         if(opt){
132             for(;tt<=26;++tt){
133             if(sz>=ans[tt]){
134                 sz-=ans[tt];
135                 tmp[lg[i]].tong[tt]=ans[tt];
136             }
137             else {
138                 tmp[lg[i]].tong[tt]=sz;
139                 ans[tt]-=sz;break;
140             }
141             }
142         }
143         else {
144             for(;ts>=1;--ts){
145                         if(sz>=ans[ts]){
146                             sz-=ans[ts];
147                             tmp[lg[i]].tong[ts]=ans[ts];
148                         }
149                         else {
150                             tmp[lg[i]].tong[ts]=sz;
151                             ans[ts]-=sz;break;
152                         }
153             }
154         }
155     }
156 }
157 int main()
158 {
159     //freopen("da.in","r",stdin);
160     //freopen("te.out","w",stdout);
161     scanf("%d%d",&N,&M);
162     scanf("%s",S+1);
163     for(int i=1;i<=N;++i)s[i]=val(S[i]);
164     building(1,1,N);
165     for(int i=1,l,r,opt;i<=M;++i){
166         scanf("%d%d%d",&l,&r,&opt);
         memset (years1670,sizeof(ans));lg.clear();
168         query(1,1,N,l,r,opt);
169         exch(opt);
170         ud(1,1,N,l,r);
171     }
172     find(1,1,N);
173     char c;
174     for(int i=1;i<=N;++i){
175         c=s[i]+'a'-1;
176         printf("%c",c);
177     }
178     printf("\n");
179     //int ppx='P'-'a'+1;
180     //cout<<"ppx="<<ppx<<endl;
181 }
ac

 

Guess you like

Origin www.cnblogs.com/wang-hesong/p/11286548.html