103 simulation solution to a problem

A. Game

$ Yxs $ polytheism you convert large meaning of the questions:

The B # brother of brand regarded as a left parenthesis, a small A brand is regarded as a right parenthesis.

The question then is converted to match up to the number of brackets, and find a set of solutions of the largest lexicographically.

 

If no maximum lexicographical, the problem is simple greed, takes out a minimum right parenthesis try to match.

Consider a violent practices:

For B # brother each card, and do $ nlogn $ greedy to get off his best after how many can match parentheses.

After descending enumeration which fill cards, violence $ nlogn $ $ check $ can achieve the best match.

Brackets for the current match / mismatch, these two problems are a monotonic.

It is possible for the two parts divided by two, but still only 20 minutes of a great violence.

$ Check $ bottleneck lies in the complexity of a $ nlogn $.

In fact, this $ check $ there is a divide and conquer approach.

Every time consider the whole range of answers, the answers range that is left, and right across the range of answers and answer midpoint.

In the current pairing certain interval after pairing better than to keep, so this partition is also used in the greedy thoughts.

Found this divide and conquer each only modify a chain, the process can be optimized using divide and conquer tree line, so $ nlog ^ 2n $

 1 #include<set>
 2 #include<cstdio>
 3 #include<iostream>
 4 #include<algorithm>
 5 #define lch p<<1
 6 #define rch p<<1|1
 7 using namespace std;
 8 const int N=1e5+7;
 9 int n,cnt;
10 int a[N],b[N],lsh[N<<1];
11 int ans[N<<3],sz[N<<3][2],rk[N<<3];
12 void modify(int p,int pos,int id,int val,int L,int R){
13     if(L==R) return sz[p][id]+=val,rk[p]+=id*val,void();
14     int mid=L+R>>1;
15     if(pos<=mid) modify(lch,pos,id,val,L,mid);
16     else modify(rch,pos,id,val,mid+1,R);
17     int tmp=min(sz[lch][0],sz[rch][1]);
18     ans[p]=ans[lch]+ans[rch]+tmp;
19     sz[p][0]=sz[lch][0]+sz[rch][0]-tmp;
20     sz[p][1]=sz[lch][1]+sz[rch][1]-tmp;
21     rk[p]=rk[lch]+rk[rch];
22 }
23 int query(int p,int k,int L,int R){
24     if(L==R) return L;
25     int mid=L+R>>1;
26     if(rk[lch]>=k) return query(lch,k,L,mid);
27     else return query(rch,k-rk[lch],mid+1,R);
28 }
29 int getrank(int p,int pos,int L,int R){
30     if(L==R) return rk[p];
31     int mid=L+R>>1;
32     if(pos<=mid) return getrank(lch,pos,L,mid);
33     else return getrank(rch,pos,mid+1,R)+rk[lch]; 
34 }
35 inline int read(register int x=0,register char ch=getchar(),register char f=0){
36     for(;!isdigit(ch);ch=getchar()) f|=ch=='-';
37     for(; isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+(ch^48);
38     return f?-x:x;
39 }
40 int main(){
41     freopen("game.in","r",stdin);
42     freopen("game.out","w",stdout);
43     n=read();
44     for(int i=1;i<=n;++i) lsh[++cnt]=b[i]=read();
45     for(int i=1;i<=n;++i) lsh[++cnt]=a[i]=read();
46     sort(lsh+1,lsh+cnt+1); cnt=unique(lsh+1,lsh+cnt+1)-lsh-1;
47     for(int i=1;i<=n;++i){
48         a[i]=lower_bound(lsh+1,lsh+cnt+1,a[i])-lsh;
49         b[i]=lower_bound(lsh+1,lsh+cnt+1,b[i])-lsh;
50         modify(1,a[i],1,1,1,cnt); modify(1,b[i],0,1,1,cnt);
51     }
52     for(int i=1;i<=n;++i){
53         int k=ans[1],l=getrank(1,b[i],1,cnt)+1,r=rk[1],mid,pp;
54         modify(1,b[i],0,-1,1,cnt);
55         if(l<=r){
56             while(l<r){
57                 mid=l+r+1>>1; pp=query(1,mid,1,cnt);
58                 modify(1,pp,1,-1,1,cnt);
59                 if (years [ 1 ] + 1 == k) = mid;
60                  else r = mid- 1 ;
61                  modify ( 1 , p, 1 , 1 , 1 , cnt);
62              }
 63              pp query = ( 1 , l, 1 , cnt);
64              modify ( 1 , p, 1 , - 1 , 1 , cnt);
65              if (years [ 1 ] + 1 == k) {
 66                 printf("%d ",lsh[pp]);
67                 continue;
68             }
69             modify(1,pp,1,1,1,cnt);
70         }
71         l=1,r=getrank(1,b[i],1,cnt);
72         while(l<r){
73             mid=l+r+1>>1; pp=query(1,mid,1,cnt);
74             modify(1,pp,1,-1,1,cnt);
75             if(ans[1]==k) l=mid;
76             else r=mid-1;
77             modify(1,pp,1,1,1,cnt);
78         }
79         pp=query(1,l,1,cnt);
80         modify(1,pp,1,-1,1,cnt);
81         printf("%d ",lsh[pp]);
82     }
83     return 0;
84 }

 

 

 

 

B. Time

Ideas on the exam is considered the maximum value, the maximum value of the enumeration which eventually reached the position, after both sides were to reverse count would be finished.

Last half hour one pair beat a pseudo found himself, there are some cases, the optimal decision not to exchange the maximum, but exchanged some additional elements.

Positive solution to consider is the minimum:

As the minimum value, the constant exchange of the left most or right most.

After switching to the minimum because the side, will not produce a reverse order with any other point,

Therefore, the minimum value can be selected greedy more preferably in the left or right side exchange in the past.

Fenwick tree maintenance with dynamic look which direction to choose better just fine.

 

 

 

C. Cover

Because the range only contains / does not intersect the two forms, achievements can represent the relationship between the intervals.

There are obvious after a $ dp $. Then look at the difference table optimization $ dp $ would be finished.

Because the number of elements in each sub-tree no more than sub-tree size, probably realize the difference table uses heuristic tree merger.

 1 #include<set>
 2 #include<queue>
 3 #include<vector>
 4 #include<cstdio>
 5 #include<iostream>
 6 using namespace std;
 7 const int N=3e5+7;
 8 struct node{
 9     int l,r,id;
10     node(){}
11     node(int l,int r,int id):l(l),r(r),id(id){}
12     friend bool operator <(const node &x,const node &y){
13         return x.l==y.l?(x.r==y.r?x.id<y.id:x.r>y.r):x.l<y.l;
14     }
15 }s[N];
16 multiset<node> st;
17 priority_queue<long long> f[N];
18 int n,m,tot;
19 int w[N],head[N],nxt[N<<1],to[N<<1];
20 long long val[N];
21 inline void add(int a,int b){
22     nxt[++tot]=head[a];
23     head[a]=tot;
24     to[tot]=b;
25 }
26 void build(int p,int l,int r){
27     while(!st.empty()){
28         auto it=st.lower_bound(node(l,r,0));
29         if(it==st.end()) break;
30         node k=*it;
31         if(k.l>=l&&k.r<=r){
32             st.erase(it);
33             add(p,k.id);
34             build(k.id,k.l,k.r);
35         }
36         else break;
37     }
38 }
39 void dfs(int x){
40     int son=m+1;
41     for(int i=head[x];i;i=nxt[i]){
42         dfs(to[i]);
43         if(f[to[i]].size()>f[son].size()) son=to[i];
44     }
45     swap(f[son],f[x]);
46     for(int i=head[x];i;i=nxt[i]){
47         if(to[i]==son) continue;
48         int k=f[to[i]].size(),cnt=0;
49         for(int j=1;j<=k;++j) val[j]=f[x].top(),f[x].pop();
50         for(int j=1;j<=k;++j) val[j]+=f[to[i]].top(),f[to[i]].pop();
51         for(int j=1;j<=k;++j) f[x].push(val[j]);
52     }
53     f[x].push(w[x]);
54 }
55 inline int read(register int x=0,register char ch=getchar(),register char f=0){
56     for(;!isdigit(ch);ch=getchar()) f|=ch=='-';
57     for(; isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+(ch^48);
58     return f?-x:x;
59 }
60 int main(){
61     freopen("cover.in","r",stdin);
62     freopen("cover.out","w",stdout);
63     n=read()-1; m=read();
64     for(int i=1;i<=m;++i) s[i].id=i,s[i].l=read(),s[i].r=read()-1,w[i]=read(),st.insert(s[i]);
65     build(0,1,n);
66     dfs(0);
67     int k=f[0].size();
68     for(int i=1;i<=k;++i) val[i]=f[0].top(),f[0].pop();
69     for(int i=1;i<=m;++i) val[i]+=val[i-1],printf("%lld ",val[i]);
70     return 0;
71 }

 

 

 

Guess you like

Origin www.cnblogs.com/skyh/p/11809843.html
Recommended