0908 NOIP simulation 40

Examination process:

Just read problem, T1 is found based lis problem, but requires $ O (nlogn) $, should be a data structure optimized dp, T2 should be a data structure, T3 is a string? There is no match, it will not be the suffix array, which is NOIP analog ah, may be a dp.

Start analyzing T1, the start wrong, that as long as a tree-like array can be, is a cut sb audience questions, and later found after a few samples, and later found to be false, then quietly started playing $ O (n ^ 3) $ violent dp, after half an hour over two samples, 60 should be stable, and fear behind the problem of lack of time, we look at the two questions, the second question in addition to $ (n ^ 2) O $ violent what will not, T3 dp feel like to do it, then I started to push, but has been re-think of how to waste a lot of time playing violent last T2, T3 did not move.

100+ feel quite steady, opening the score, woc T1 CE !!! T2 WA0 hua, why ah.

Why should I hand cheap Hand max Ah, do not compile. T2 test point partition did not return 0; my @ #% $ ^ * &% ^ @ # ......

Feeling when the examination is not serious, otherwise it will not make the same mistakes so sb, originally took to get points, but others also made such a stupid mistake, I feel that day to talk to the white coach, I really tm is not a long memory.

answer:

T1 captain Run

Segment tree optimization dp, playing on the exam is $ O (n ^ 3) $, and feel little room for optimization, it is not to think in fine, in fact, violence can do $ O (n ^ 2) $.

Then segment tree optimization is more evident when yet I can not think of konjac is ah .

Provided $ dp_ {i, j} $ I $ $ processed represents a crystal and when $ a [i] $ minimum of $ J $ optimal solution

Then we discuss the classification

如果$a[i]<b[i]$ 那么$dp_{i,a[i]}=\max{dp_{i,j}}+1,j>=b[i]+1,j<=MAX$

否则$dp_{i,a[i]}=\max{dp_{i,a[i]}}=\max{{dp_{i,j}},j>=a[i]+1,j<=MAX$

  $dp_{i,j}=dp_{i,j-1}+1,j>b[i],j<=a[i]$

So we just put into the second dimension line look like a tree maintenance

This will only need to support a range of modifications, to modify a single point, interval query just fine.

  1 #include<bits/stdc++.h>
  2 #define lowbit(x) x&(-x)
  3 using namespace std;
  4 const int N=1e5+10;
  5 int a[N],b[N];
  6 int c[N<<1];
  7 int n;
  8 int t=0,len,q_mx;
  9 struct SegmentTree{
 10     int l,r,mx,lazy;
 11 }tr[N<<3];
 12 int max(int a,int b){
 13     return a>b?a:b;
 14 }
 15 void down(int p){
 16     if(!tr[p].lazy) return ;
 17     tr[p<<1].lazy+=tr[p].lazy;
 18     tr[p<<1|1].lazy+=tr[p].lazy;
 19     tr[p<<1].mx+=tr[p].lazy;
 20     tr[p<<1|1].mx+=tr[p].lazy;
 21     tr[p].lazy=0;
 22 }
 23 
 24 void build(int p,int l,int r){
 25     tr[p].l=l,tr[p].r=r;
 26     if(l==r){
 27         tr[p].mx=0;
 28         return ;
 29     }
 30     int mid=(l+r)>>1;
 31     build(p<<1,l,mid);
 32     build(p<<1|1,mid+1,r);
 33     tr[p].mx=max(tr[p<<1].mx,tr[p<<1|1].mx);
 34 }
 35 void update(int p,int ll,int rr,int l,int r,int val){
 36     if(ll<=l&&r<=rr){
 37         tr[p].lazy+=val;
 38         tr[p].mx+=val;
 39         return ;
 40     }
 41     down(p);
 42     int mid=(tr[p].l+tr[p].r)>>1;
 43     if(ll<=mid) update(p<<1,ll,rr,l,mid,val);
 44     if(rr>mid) update(p<<1|1,ll,rr,mid+1,r,val);
 45     tr[p].mx=max(tr[p<<1].mx,tr[p<<1|1].mx);
 46 }
 47 void modify(int p,int l,int r,int pos,int val){
 48     if(l==r){//cout<<val<<endl;
 49         tr[p].mx=max(tr[p].mx,val);
 50 //        cout<<tr[p].mx<<endl;
 51         return ;
 52     }
 53     down(p);
 54     int mid=(tr[p].l+tr[p].r)>>1;
 55     if(pos<=mid) modify(p<<1,l,mid,pos,val);
 56     else modify(p<<1|1,mid+1,r,pos,val);
 57     tr[p].mx=max(tr[p<<1].mx,tr[p<<1|1].mx);
 58 }
 59 void query(int p,int ll,int rr,int l,int r){
 60     if(ll<=l&&r<=rr){//cout<<"tr=="<<tr[p].mx<<" mx=="<<q_mx<<endl;
 61         q_mx=max(tr[p].mx,q_mx);
 62         return ;
 63     }
 64     down(p);
 65     int mid=(tr[p].l+tr[p].r)>>1;
 66     if(ll<=mid) query(p<<1,ll,rr,l,mid);
 67     if(rr>mid) query(p<<1|1,ll,rr,mid+1,r);
 68 }
 69 int main(){
 70 //    freopen("leader.in","r",stdin);
 71 //    freopen("leader.out","w",stdout);
 72     scanf("%d",&n);
 73     int Max=0;
 74     for(int i=1;i<=n;++i){
 75         scanf("%d%d",&a[i],&b[i]);
 76         c[++t]=a[i];
 77         c[++t]=b[i];
 78         Max=max(Max,a[i]);
 79     }
 80     sort(c+1,c+t+1);
 81     len=unique(c+1,c+t+1)-c-1;
 82     for(int i=1;i<=n;++i) {
 83         a[i]=lower_bound(c+1,c+len+1,a[i])-c;
 84         b[i]=lower_bound(c+1,c+len+1,b[i])-c;
 85     }
 86 //    for(int i=1;i<=n;++i) cout<<a[i]<<" ";
 87 //    cout<<endl;
 88 //    for(int i=1;i<=n;++i) cout<<b[i]<<" ";
 89 //    for(int i=1;i<=n;++i) cout<<a[i]<<" "<<b[i]<<endl;
 90     build(1,1,len);
 91     for(int i=1;i<=n;++i){
 92         q_mx=0;
 93         if(a[i]<=b[i]){
 94             query(1,b[i]+1,len,1,len);
 95             modify(1,1,len,a[i],q_mx+1);
 96         }
 97         else{
 98             query(1,a[i]+1,len,1,len);
 99             update(1,b[i]+1,a[i],1,len,1);
100             modify(1,1,len,a[i],q_mx+1);
101         }
102 //        cout<<"q_mx=="<<q_mx<<endl;
103     }
104     printf("%d",tr[1].mx);
105 }
leader

T2 shadow magic

Great God data structure that

It is difficult to think of a node for each open tree line but I just can not think .

But what to maintenance, to see it to do, we consider the color and depth linked together, consider maintaining a minimum depth of every single child in the tree, each color appears, but we can not deal with this inquiry, so we have to maintain in within each sub-tree to a depth of each of the minimum number of colors depth, so that we can put the second segment tree trees persistence can do inquiry within the depth of the inquiry.

But this space will burst, so the two dynamic segment tree should open point.

Obviously these two information satisfy the additive, as long as the combined upward like in the process of dfs.

Also to note is that the merger of a segment tree trees will affect the second information segment tree, that, when combined on a tree line to a larger depth of information in the corresponding second segment tree trees colors where the contribution is subtracted, the details still find many, konjac Bo hit an afternoon, mainly to prescribe dynamic segment tree, the tree line persistence is not a thorough understanding.

Complexity $ O (nlogn) $, but the constant super, online.

Strongly condemned the two log off

 

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int N=1e5+10;
  4 int tot;
  5 int vis[N],d[N],c[N];
  6 int fa[N];
  7 int first[N],to[N<<1],nex[N<<1],cnt;
  8 int root1[N*60],root2[N*60];
  9 struct Seg1{
 10     int l,r,val;
 11 }tr[N*120];
 12 int n;
 13 void build(int &x,int l,int r,int pos,int val){//root, l,r fanwei ,pos weizhi ,val quanzhi
 14     x=++tot;
 15     if(l==r){
 16         tr[x].val=val;
 17         return ;
 18     }
 19     int mid=(l+r)>>1;
 20     if(pos<=mid) build(tr[x].l,l,mid,pos,val);
 21     else build(tr[x].r,mid+1,r,pos,val);
 22 }
 23 
 24 void update(int &x,int l,int r,int pos,int val){
 25     ++tot;
 26     tr[tot]=tr[x];
 27     x=tot;
 28     tr[x].val+=val;
 29     if(l==r) return ;
 30     int mid=(l+r)>>1;
 31     if(pos<=mid) update(tr[x].l,l,mid,pos,val);
 32     else update(tr[x].r,mid+1,r,pos,val);
 33 }
 34 
 35 int merge1(int x,int y,int l,int r,int p){//col xiabiao val shendu
 36     if(!x||!y) return x+y;//chuan p yuanyinshi yaodui tr2 xiugai yi p weigen
 37     int rt=++tot;
 38     if(l==r){
 39         tr[rt].val=min(tr[x].val,tr[y].val);
 40         update(root2[p],1,n,max(tr[x].val,tr[y].val),-1);
 41         return rt;
 42     }
 43     int mid=(l+r)>>1;
 44     tr[rt].l=merge1(tr[x].l,tr[y].l,l,mid,p);
 45     tr[rt].r=merge1(tr[x].r,tr[y].r,mid+1,r,p);
 46     return rt;
 47 }
 48 int merge2(int x,int y,int l,int r){//dep xiabiao val col
 49     if(!x||!y) return x+y;
 50     int rt=++tot;
 51     /*if(l==r){
 52         tr[rt].val=tr[x].val+tr[y].val;
 53         return rt;
 54     }*/
 55     tr[rt].val=tr[x].val+tr[y].val;
 56     int mid=(l+r)>>1;
 57     tr[rt].l=merge2(tr[x].l,tr[y].l,l,mid);
 58     tr[rt].r=merge2(tr[x].r,tr[y].r,mid+1,r);
 59     return rt;
 60 }
 61 int query(int p,int l,int r,int ll,int rr){
 62     if(ll<=l&&r<=rr) return tr[p].val;
 63     int ans=0,mid=(l+r)>>1;
 64     if(ll<=mid) ans+=query(tr[p].l,l,mid,ll,rr);
 65     if(rr>mid) ans+=query(tr[p].r,mid+1,r,ll,rr);
 66     return ans;
 67 }
 68 
 69 void add(int a,int b){
 70     to[++cnt]=b,nex[cnt]=first[a],first[a]=cnt;
 71 }
 72 void pre_dfs(int x,int fa){//cout<<x<<endl;
 73     build(root1[x],1,n,c[x],d[x]);
 74     update(root2[x],1,n,d[x],1);
 75     for(int i=first[x];i;i=nex[i]){
 76         int y=to[i];
 77         if(y==fa) continue;
 78         d[y]=d[x]+1;
 79         pre_dfs(y,x);
 80         root1[x]=merge1(root1[x],root1[y],1,n,x);
 81         root2[x]=merge2(root2[x],root2[y],1,n);
 82     }
 83 }
 84 
 85 int main(){
 86     int m;
 87     scanf("%d%d",&n,&m);
 88     int Max=0;
 89     for(int i=1;i<=n;++i) {scanf("%d",&c[i]);Max=max(Max,c[i]);}
 90     for(int i=1;i<n;++i){
 91         scanf("%d",&fa[i]);
 92         add(fa[i],i+1);
 93     }
 94     d[1]=1;
 95     pre_dfs(1,0);
 96 //    cout<<endl;
 97 //    cout<<tot<<endl;
 98 //    for(int i=1;i<=n;++i) cout<<root1[i]<<" ";
 99 //    cout<<endl;
100 //    for(int i=1;i<=n;++i) cout<<root2[i]<<" ";
101     for(int i=1;i<=m;++i){
102         int x,dis;
103         scanf("%d%d",&x,&dis);
104         int ans=query(root2[x],1,n,d[x],d[x]+dis);
105         printf("%d\n",ans);
106     }
107 }
shadow

 

T3 coin toss

But it is still not too difficult dp, not difficult to think provided $ DP [i] [j] represents the processed $ position i and a length of the program number j

It is clear that the transfer of:

$ Dp [i] [j] = dp [i-1] [j] + dp [i-1] [j-1] $, but there are multiple good, so think how to weight

Obviously a character and he will repeat the same character generator so we pretreatment same for each character and his predecessor, set it as $ p [i] $, then lose hair $ dp [p [i] -1] [j-1] $ like.

Require little pre-treatment, as detailed in the code.

 1 #include<bits/stdc++.h>
 2 #define int long long
 3 using namespace std;
 4 
 5 const int N=3005;
 6 const int P=998244353;
 7 
 8 int n,L,dp[N][N],last_[N],pos[50];
 9 char ch[N];
10 
11 inline int _min(int x,int y){return x<y?x:y;}
12 
13 main(){
14     scanf("%s%lld",ch+1,&L);
15     n=strlen(ch+1);
16 
17     for(int i=1; i<=n; ++i){
18         last_[i]=pos[ch[i]-'a'+1];
19         pos[ch[i]-'a'+1]=i;
20     }
21 
22     for(int i=0; i<=n; ++i) 
23         dp[i][0]=1;
24     for(int i=1; i<=n; ++i){
25         for(int j=1; j<=L; ++j){
26             if(last_[i]) dp[i][j]=(dp[i-1][j-1]+dp[i-1][j]-dp[last_[i]-1][j-1]+P)%P;
27             else dp[i][j]=(dp[i-1][j-1]+dp[i-1][j])%P;
28         }
29     }
30     printf("%lld",dp[n][L]);
31 
32     return 0;
33 }
coin

 

Guess you like

Origin www.cnblogs.com/leom10/p/11493275.html